|  |  | # ASAP
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | [](https://travis-ci.org/kriskowal/asap)
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Promise and asynchronous observer libraries, as well as hand-rolled callback
 | 
						
						
						
							|  |  | programs and libraries, often need a mechanism to postpone the execution of a
 | 
						
						
						
							|  |  | callback until the next available event.
 | 
						
						
						
							|  |  | (See [Designing API’s for Asynchrony][Zalgo].)
 | 
						
						
						
							|  |  | The `asap` function executes a task **as soon as possible** but not before it
 | 
						
						
						
							|  |  | returns, waiting only for the completion of the current event and previously
 | 
						
						
						
							|  |  | scheduled tasks.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```javascript
 | 
						
						
						
							|  |  | asap(function () {
 | 
						
						
						
							|  |  |     // ...
 | 
						
						
						
							|  |  | });
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | [Zalgo]: http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | This CommonJS package provides an `asap` module that exports a function that
 | 
						
						
						
							|  |  | executes a task function *as soon as possible*.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ASAP strives to schedule events to occur before yielding for IO, reflow,
 | 
						
						
						
							|  |  | or redrawing.
 | 
						
						
						
							|  |  | Each event receives an independent stack, with only platform code in parent
 | 
						
						
						
							|  |  | frames and the events run in the order they are scheduled.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ASAP provides a fast event queue that will execute tasks until it is
 | 
						
						
						
							|  |  | empty before yielding to the JavaScript engine's underlying event-loop.
 | 
						
						
						
							|  |  | When a task gets added to a previously empty event queue, ASAP schedules a flush
 | 
						
						
						
							|  |  | event, preferring for that event to occur before the JavaScript engine has an
 | 
						
						
						
							|  |  | opportunity to perform IO tasks or rendering, thus making the first task and
 | 
						
						
						
							|  |  | subsequent tasks semantically indistinguishable.
 | 
						
						
						
							|  |  | ASAP uses a variety of techniques to preserve this invariant on different
 | 
						
						
						
							|  |  | versions of browsers and Node.js.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | By design, ASAP prevents input events from being handled until the task
 | 
						
						
						
							|  |  | queue is empty.
 | 
						
						
						
							|  |  | If the process is busy enough, this may cause incoming connection requests to be
 | 
						
						
						
							|  |  | dropped, and may cause existing connections to inform the sender to reduce the
 | 
						
						
						
							|  |  | transmission rate or stall.
 | 
						
						
						
							|  |  | ASAP allows this on the theory that, if there is enough work to do, there is no
 | 
						
						
						
							|  |  | sense in looking for trouble.
 | 
						
						
						
							|  |  | As a consequence, ASAP can interfere with smooth animation.
 | 
						
						
						
							|  |  | If your task should be tied to the rendering loop, consider using
 | 
						
						
						
							|  |  | `requestAnimationFrame` instead.
 | 
						
						
						
							|  |  | A long sequence of tasks can also effect the long running script dialog.
 | 
						
						
						
							|  |  | If this is a problem, you may be able to use ASAP’s cousin `setImmediate` to
 | 
						
						
						
							|  |  | break long processes into shorter intervals and periodically allow the browser
 | 
						
						
						
							|  |  | to breathe.
 | 
						
						
						
							|  |  | `setImmediate` will yield for IO, reflow, and repaint events.
 | 
						
						
						
							|  |  | It also returns a handler and can be canceled.
 | 
						
						
						
							|  |  | For a `setImmediate` shim, consider [YuzuJS setImmediate][setImmediate].
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | [setImmediate]: https://github.com/YuzuJS/setImmediate
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Take care.
 | 
						
						
						
							|  |  | ASAP can sustain infinite recursive calls without warning.
 | 
						
						
						
							|  |  | It will not halt from a stack overflow, and it will not consume unbounded
 | 
						
						
						
							|  |  | memory.
 | 
						
						
						
							|  |  | This is behaviorally equivalent to an infinite loop.
 | 
						
						
						
							|  |  | Just as with infinite loops, you can monitor a Node.js process for this behavior
 | 
						
						
						
							|  |  | with a heart-beat signal.
 | 
						
						
						
							|  |  | As with infinite loops, a very small amount of caution goes a long way to
 | 
						
						
						
							|  |  | avoiding problems.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```javascript
 | 
						
						
						
							|  |  | function loop() {
 | 
						
						
						
							|  |  |     asap(loop);
 | 
						
						
						
							|  |  | }
 | 
						
						
						
							|  |  | loop();
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | In browsers, if a task throws an exception, it will not interrupt the flushing
 | 
						
						
						
							|  |  | of high-priority tasks.
 | 
						
						
						
							|  |  | The exception will be postponed to a later, low-priority event to avoid
 | 
						
						
						
							|  |  | slow-downs.
 | 
						
						
						
							|  |  | In Node.js, if a task throws an exception, ASAP will resume flushing only if—and
 | 
						
						
						
							|  |  | only after—the error is handled by `domain.on("error")` or
 | 
						
						
						
							|  |  | `process.on("uncaughtException")`.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## Raw ASAP
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Checking for exceptions comes at a cost.
 | 
						
						
						
							|  |  | The package also provides an `asap/raw` module that exports the underlying
 | 
						
						
						
							|  |  | implementation which is faster but stalls if a task throws an exception.
 | 
						
						
						
							|  |  | This internal version of the ASAP function does not check for errors.
 | 
						
						
						
							|  |  | If a task does throw an error, it will stall the event queue unless you manually
 | 
						
						
						
							|  |  | call `rawAsap.requestFlush()` before throwing the error, or any time after.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | In Node.js, `asap/raw` also runs all tasks outside any domain.
 | 
						
						
						
							|  |  | If you need a task to be bound to your domain, you will have to do it manually.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```js
 | 
						
						
						
							|  |  | if (process.domain) {
 | 
						
						
						
							|  |  |     task = process.domain.bind(task);
 | 
						
						
						
							|  |  | }
 | 
						
						
						
							|  |  | rawAsap(task);
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## Tasks
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | A task may be any object that implements `call()`.
 | 
						
						
						
							|  |  | A function will suffice, but closures tend not to be reusable and can cause
 | 
						
						
						
							|  |  | garbage collector churn.
 | 
						
						
						
							|  |  | Both `asap` and `rawAsap` accept task objects to give you the option of
 | 
						
						
						
							|  |  | recycling task objects or using higher callable object abstractions.
 | 
						
						
						
							|  |  | See the `asap` source for an illustration.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## Compatibility
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ASAP is tested on Node.js v0.10 and in a broad spectrum of web browsers.
 | 
						
						
						
							|  |  | The following charts capture the browser test results for the most recent
 | 
						
						
						
							|  |  | release.
 | 
						
						
						
							|  |  | The first chart shows test results for ASAP running in the main window context.
 | 
						
						
						
							|  |  | The second chart shows test results for ASAP running in a web worker context.
 | 
						
						
						
							|  |  | Test results are inconclusive (grey) on browsers that do not support web
 | 
						
						
						
							|  |  | workers.
 | 
						
						
						
							|  |  | These data are captured automatically by [Continuous
 | 
						
						
						
							|  |  | Integration][].
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | [Continuous Integration]: https://github.com/kriskowal/asap/blob/master/CONTRIBUTING.md
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## Caveats
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | When a task is added to an empty event queue, it is not always possible to
 | 
						
						
						
							|  |  | guarantee that the task queue will begin flushing immediately after the current
 | 
						
						
						
							|  |  | event.
 | 
						
						
						
							|  |  | However, once the task queue begins flushing, it will not yield until the queue
 | 
						
						
						
							|  |  | is empty, even if the queue grows while executing tasks.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | The following browsers allow the use of [DOM mutation observers][] to access
 | 
						
						
						
							|  |  | the HTML [microtask queue][], and thus begin flushing ASAP's task queue
 | 
						
						
						
							|  |  | immediately at the end of the current event loop turn, before any rendering or
 | 
						
						
						
							|  |  | IO:
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | [microtask queue]: http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#microtask-queue
 | 
						
						
						
							|  |  | [DOM mutation observers]: http://dom.spec.whatwg.org/#mutation-observers
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | - Android 4–4.3
 | 
						
						
						
							|  |  | - Chrome 26–34
 | 
						
						
						
							|  |  | - Firefox 14–29
 | 
						
						
						
							|  |  | - Internet Explorer 11
 | 
						
						
						
							|  |  | - iPad Safari 6–7.1
 | 
						
						
						
							|  |  | - iPhone Safari 7–7.1
 | 
						
						
						
							|  |  | - Safari 6–7
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | In the absense of mutation observers, there are a few browsers, and situations
 | 
						
						
						
							|  |  | like web workers in some of the above browsers,  where [message channels][]
 | 
						
						
						
							|  |  | would be a useful way to avoid falling back to timers.
 | 
						
						
						
							|  |  | Message channels give direct access to the HTML [task queue][], so the ASAP
 | 
						
						
						
							|  |  | task queue would flush after any already queued rendering and IO tasks, but
 | 
						
						
						
							|  |  | without having the minimum delay imposed by timers.
 | 
						
						
						
							|  |  | However, among these browsers, Internet Explorer 10 and Safari do not reliably
 | 
						
						
						
							|  |  | dispatch messages, so they are not worth the trouble to implement.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | [message channels]: http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#message-channels
 | 
						
						
						
							|  |  | [task queue]: http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#concept-task
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | - Internet Explorer 10
 | 
						
						
						
							|  |  | - Safair 5.0-1
 | 
						
						
						
							|  |  | - Opera 11-12
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | In the absense of mutation observers, these browsers and the following browsers
 | 
						
						
						
							|  |  | all fall back to using `setTimeout` and `setInterval` to ensure that a `flush`
 | 
						
						
						
							|  |  | occurs.
 | 
						
						
						
							|  |  | The implementation uses both and cancels whatever handler loses the race, since
 | 
						
						
						
							|  |  | `setTimeout` tends to occasionally skip tasks in unisolated circumstances.
 | 
						
						
						
							|  |  | Timers generally delay the flushing of ASAP's task queue for four milliseconds.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | - Firefox 3–13
 | 
						
						
						
							|  |  | - Internet Explorer 6–10
 | 
						
						
						
							|  |  | - iPad Safari 4.3
 | 
						
						
						
							|  |  | - Lynx 2.8.7
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## Heritage
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ASAP has been factored out of the [Q][] asynchronous promise library.
 | 
						
						
						
							|  |  | It originally had a naïve implementation in terms of `setTimeout`, but
 | 
						
						
						
							|  |  | [Malte Ubl][NonBlocking] provided an insight that `postMessage` might be
 | 
						
						
						
							|  |  | useful for creating a high-priority, no-delay event dispatch hack.
 | 
						
						
						
							|  |  | Since then, Internet Explorer proposed and implemented `setImmediate`.
 | 
						
						
						
							|  |  | Robert Katić began contributing to Q by measuring the performance of
 | 
						
						
						
							|  |  | the internal implementation of `asap`, paying particular attention to
 | 
						
						
						
							|  |  | error recovery.
 | 
						
						
						
							|  |  | Domenic, Robert, and Kris Kowal collectively settled on the current strategy of
 | 
						
						
						
							|  |  | unrolling the high-priority event queue internally regardless of what strategy
 | 
						
						
						
							|  |  | we used to dispatch the potentially lower-priority flush event.
 | 
						
						
						
							|  |  | Domenic went on to make ASAP cooperate with Node.js domains.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | [Q]: https://github.com/kriskowal/q
 | 
						
						
						
							|  |  | [NonBlocking]: http://www.nonblocking.io/2011/06/windownexttick.html
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | For further reading, Nicholas Zakas provided a thorough article on [The
 | 
						
						
						
							|  |  | Case for setImmediate][NCZ].
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | [NCZ]: http://www.nczonline.net/blog/2013/07/09/the-case-for-setimmediate/
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Ember’s RSVP promise implementation later [adopted][RSVP ASAP] the name ASAP but
 | 
						
						
						
							|  |  | further developed the implentation.
 | 
						
						
						
							|  |  | Particularly, The `MessagePort` implementation was abandoned due to interaction
 | 
						
						
						
							|  |  | [problems with Mobile Internet Explorer][IE Problems] in favor of an
 | 
						
						
						
							|  |  | implementation backed on the newer and more reliable DOM `MutationObserver`
 | 
						
						
						
							|  |  | interface.
 | 
						
						
						
							|  |  | These changes were back-ported into this library.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | [IE Problems]: https://github.com/cujojs/when/issues/197
 | 
						
						
						
							|  |  | [RSVP ASAP]: https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | In addition, ASAP factored into `asap` and `asap/raw`, such that `asap` remained
 | 
						
						
						
							|  |  | exception-safe, but `asap/raw` provided a tight kernel that could be used for
 | 
						
						
						
							|  |  | tasks that guaranteed that they would not throw exceptions.
 | 
						
						
						
							|  |  | This core is useful for promise implementations that capture thrown errors in
 | 
						
						
						
							|  |  | rejected promises and do not need a second safety net.
 | 
						
						
						
							|  |  | At the same time, the exception handling in `asap` was factored into separate
 | 
						
						
						
							|  |  | implementations for Node.js and browsers, using the the [Browserify][Browser
 | 
						
						
						
							|  |  | Config] `browser` property in `package.json` to instruct browser module loaders
 | 
						
						
						
							|  |  | and bundlers, including [Browserify][], [Mr][], and [Mop][],  to use the
 | 
						
						
						
							|  |  | browser-only implementation.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | [Browser Config]: https://gist.github.com/defunctzombie/4339901
 | 
						
						
						
							|  |  | [Browserify]: https://github.com/substack/node-browserify
 | 
						
						
						
							|  |  | [Mr]: https://github.com/montagejs/mr
 | 
						
						
						
							|  |  | [Mop]: https://github.com/montagejs/mop
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## License
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Copyright 2009-2014 by Contributors
 | 
						
						
						
							|  |  | MIT License (enclosed)
 | 
						
						
						
							|  |  | 
 |