123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- // Use the fastest possible means to execute a task in a future turn
- // of the event loop.
- // linked list of tasks (single, with head node)
- var head = {task: void 0, next: null};
- var tail = head;
- var flushing = false;
- var requestFlush = void 0;
- var isNodeJS = false;
- function flush() {
- /* jshint loopfunc: true */
- while (head.next) {
- head = head.next;
- var task = head.task;
- head.task = void 0;
- var domain = head.domain;
- if (domain) {
- head.domain = void 0;
- domain.enter();
- }
- try {
- task();
- } catch (e) {
- if (isNodeJS) {
- // In node, uncaught exceptions are considered fatal errors.
- // Re-throw them synchronously to interrupt flushing!
- // Ensure continuation if the uncaught exception is suppressed
- // listening "uncaughtException" events (as domains does).
- // Continue in next event to avoid tick recursion.
- if (domain) {
- domain.exit();
- }
- setTimeout(flush, 0);
- if (domain) {
- domain.enter();
- }
- throw e;
- } else {
- // In browsers, uncaught exceptions are not fatal.
- // Re-throw them asynchronously to avoid slow-downs.
- setTimeout(function() {
- throw e;
- }, 0);
- }
- }
- if (domain) {
- domain.exit();
- }
- }
- flushing = false;
- }
- if (typeof process !== "undefined" && process.nextTick) {
- // Node.js before 0.9. Note that some fake-Node environments, like the
- // Mocha test runner, introduce a `process` global without a `nextTick`.
- isNodeJS = true;
- requestFlush = function () {
- process.nextTick(flush);
- };
- } else if (typeof setImmediate === "function") {
- // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
- if (typeof window !== "undefined") {
- requestFlush = setImmediate.bind(window, flush);
- } else {
- requestFlush = function () {
- setImmediate(flush);
- };
- }
- } else if (typeof MessageChannel !== "undefined") {
- // modern browsers
- // http://www.nonblocking.io/2011/06/windownexttick.html
- var channel = new MessageChannel();
- channel.port1.onmessage = flush;
- requestFlush = function () {
- channel.port2.postMessage(0);
- };
- } else {
- // old browsers
- requestFlush = function () {
- setTimeout(flush, 0);
- };
- }
- function asap(task) {
- tail = tail.next = {
- task: task,
- domain: isNodeJS && process.domain,
- next: null
- };
- if (!flushing) {
- flushing = true;
- requestFlush();
- }
- };
- module.exports = asap;
|