Blame view

node_modules/asap/asap.js 1.91 KB
ce4c83ff   wxy   初始提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  "use strict";
  
  var rawAsap = require("./raw");
  var freeTasks = [];
  
  /**
   * Calls a task as soon as possible after returning, in its own event, with
   * priority over IO events. An exception thrown in a task can be handled by
   * `process.on("uncaughtException") or `domain.on("error")`, but will otherwise
   * crash the process. If the error is handled, all subsequent tasks will
   * resume.
   *
   * @param {{call}} task A callable object, typically a function that takes no
   * arguments.
   */
  module.exports = asap;
  function asap(task) {
      var rawTask;
      if (freeTasks.length) {
          rawTask = freeTasks.pop();
      } else {
          rawTask = new RawTask();
      }
      rawTask.task = task;
      rawTask.domain = process.domain;
      rawAsap(rawTask);
  }
  
  function RawTask() {
      this.task = null;
      this.domain = null;
  }
  
  RawTask.prototype.call = function () {
      if (this.domain) {
          this.domain.enter();
      }
      var threw = true;
      try {
          this.task.call();
          threw = false;
          // If the task throws an exception (presumably) Node.js restores the
          // domain stack for the next event.
          if (this.domain) {
              this.domain.exit();
          }
      } finally {
          // We use try/finally and a threw flag to avoid messing up stack traces
          // when we catch and release errors.
          if (threw) {
              // In Node.js, uncaught exceptions are considered fatal errors.
              // Re-throw them to interrupt flushing!
              // Ensure that flushing continues if an uncaught exception is
              // suppressed listening process.on("uncaughtException") or
              // domain.on("error").
              rawAsap.requestFlush();
          }
          // If the task threw an error, we do not want to exit the domain here.
          // Exiting the domain would prevent the domain from catching the error.
          this.task = null;
          this.domain = null;
          freeTasks.push(this);
      }
  };