Skip to content

Instantly share code, notes, and snippets.

@pdokas
Last active December 28, 2015 11:29

Revisions

  1. pdokas revised this gist Nov 15, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    var asap = (function() {
    var asap = (function(global) {
    "use strict";

    // Use the fastest possible means to execute a task in a future turn
    @@ -125,4 +125,4 @@ var asap = (function() {
    };

    return asap;
    })();
    })(this);
  2. pdokas created this gist Nov 15, 2013.
    128 changes: 128 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,128 @@
    var asap = (function() {
    "use strict";

    // 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 hasSetImmediate = typeof setImmediate === "function";
    var domain;

    // Avoid shims from browserify.
    // The existence of `global` in browsers is guaranteed by browserify.
    var process = global.process;

    // Note that some fake-Node environments,
    // like the Mocha test runner, introduce a `process` global.
    var isNodeJS = !!process && ({}).toString.call(process) === "[object process]";

    function flush() {
    /* jshint loopfunc: true */

    while (head.next) {
    head = head.next;
    var task = head.task;
    head.task = void 0;

    try {
    task();

    } catch (e) {
    if (isNodeJS) {
    // In node, uncaught exceptions are considered fatal errors.
    // Re-throw them to interrupt flushing!

    // Ensure continuation if an uncaught exception is suppressed
    // listening process.on("uncaughtException") or domain("error").
    requestFlush();

    throw e;

    } else {
    // In browsers, uncaught exceptions are not fatal.
    // Re-throw them asynchronously to avoid slow-downs.
    setTimeout(function () {
    throw e;
    }, 0);
    }
    }
    }

    flushing = false;
    }

    if (isNodeJS) {
    // Node.js
    requestFlush = function () {
    // Ensure flushing is not bound to any domain.
    var currentDomain = process.domain;
    if (currentDomain) {
    domain = domain || (1,require)("domain");
    domain.active = process.domain = null;
    }

    // Avoid tick recursion - use setImmediate if it exists.
    if (flushing && hasSetImmediate) {
    setImmediate(flush);
    } else {
    process.nextTick(flush);
    }

    if (currentDomain) {
    domain.active = process.domain = currentDomain;
    }
    };

    } else if (hasSetImmediate) {
    // In IE10, or https://github.com/NobleJS/setImmediate
    requestFlush = function () {
    setImmediate(flush);
    };

    } else if (typeof MessageChannel !== "undefined") {
    // modern browsers
    // http://www.nonblocking.io/2011/06/windownexttick.html
    var channel = new MessageChannel();
    // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
    // working message ports the first time a page loads.
    channel.port1.onmessage = function () {
    requestFlush = requestPortFlush;
    channel.port1.onmessage = flush;
    flush();
    };
    var requestPortFlush = function () {
    // Opera requires us to provide a message payload, regardless of
    // whether we use it.
    channel.port2.postMessage(0);
    };
    requestFlush = function () {
    setTimeout(flush, 0);
    requestPortFlush();
    };

    } else {
    // old browsers
    requestFlush = function () {
    setTimeout(flush, 0);
    };
    }

    function asap(task) {
    if (isNodeJS && process.domain) {
    task = process.domain.bind(task);
    }

    tail = tail.next = {task: task, next: null};

    if (!flushing) {
    requestFlush();
    flushing = true;
    }
    };

    return asap;
    })();