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