You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
65 lines
1.9 KiB
65 lines
1.9 KiB
"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); |
|
} |
|
}; |
|
|
|
|