|  | "use strict"; | 
|  |  | 
|  | // rawAsap provides everything we need except exception management. | 
|  | var rawAsap = require("./raw"); | 
|  | // RawTasks are recycled to reduce GC churn. | 
|  | var freeTasks = []; | 
|  | // We queue errors to ensure they are thrown in right order (FIFO). | 
|  | // Array-as-queue is good enough here, since we are just dealing with exceptions. | 
|  | var pendingErrors = []; | 
|  | var requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError); | 
|  |  | 
|  | function throwFirstError() { | 
|  | if (pendingErrors.length) { | 
|  | throw pendingErrors.shift(); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Calls a task as soon as possible after returning, in its own event, with priority | 
|  | * over other events like animation, reflow, and repaint. An error thrown from an | 
|  | * event will not interrupt, nor even substantially slow down the processing of | 
|  | * other events, but will be rather postponed to a lower priority event. | 
|  | * @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; | 
|  | rawAsap(rawTask); | 
|  | } | 
|  |  | 
|  | // We wrap tasks with recyclable task objects.  A task object implements | 
|  | // `call`, just like a function. | 
|  | function RawTask() { | 
|  | this.task = null; | 
|  | } | 
|  |  | 
|  | // The sole purpose of wrapping the task is to catch the exception and recycle | 
|  | // the task object after its single use. | 
|  | RawTask.prototype.call = function () { | 
|  | try { | 
|  | this.task.call(); | 
|  | } catch (error) { | 
|  | if (asap.onerror) { | 
|  | // This hook exists purely for testing purposes. | 
|  | // Its name will be periodically randomized to break any code that | 
|  | // depends on its existence. | 
|  | asap.onerror(error); | 
|  | } else { | 
|  | // In a web browser, exceptions are not fatal. However, to avoid | 
|  | // slowing down the queue of pending tasks, we rethrow the error in a | 
|  | // lower priority turn. | 
|  | pendingErrors.push(error); | 
|  | requestErrorThrow(); | 
|  | } | 
|  | } finally { | 
|  | this.task = null; | 
|  | freeTasks[freeTasks.length] = this; | 
|  | } | 
|  | }; |