|
|
- "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);
- }
- };
-
|