| /** @license MIT License (c) copyright 2010-2014 original author or authors */ |
| /** @author Brian Cavalier */ |
| /** @author John Hann */ |
| |
| (function(define) { 'use strict'; |
| define(function() { |
| |
| // Credit to Twisol (https://github.com/Twisol) for suggesting |
| // this type of extensible queue + trampoline approach for next-tick conflation. |
| |
| /** |
| * Async task scheduler |
| * @param {function} async function to schedule a single async function |
| * @constructor |
| */ |
| function Scheduler(async) { |
| this._async = async; |
| this._running = false; |
| |
| this._queue = this; |
| this._queueLen = 0; |
| this._afterQueue = {}; |
| this._afterQueueLen = 0; |
| |
| var self = this; |
| this.drain = function() { |
| self._drain(); |
| }; |
| } |
| |
| /** |
| * Enqueue a task |
| * @param {{ run:function }} task |
| */ |
| Scheduler.prototype.enqueue = function(task) { |
| this._queue[this._queueLen++] = task; |
| this.run(); |
| }; |
| |
| /** |
| * Enqueue a task to run after the main task queue |
| * @param {{ run:function }} task |
| */ |
| Scheduler.prototype.afterQueue = function(task) { |
| this._afterQueue[this._afterQueueLen++] = task; |
| this.run(); |
| }; |
| |
| Scheduler.prototype.run = function() { |
| if (!this._running) { |
| this._running = true; |
| this._async(this.drain); |
| } |
| }; |
| |
| /** |
| * Drain the handler queue entirely, and then the after queue |
| */ |
| Scheduler.prototype._drain = function() { |
| var i = 0; |
| for (; i < this._queueLen; ++i) { |
| this._queue[i].run(); |
| this._queue[i] = void 0; |
| } |
| |
| this._queueLen = 0; |
| this._running = false; |
| |
| for (i = 0; i < this._afterQueueLen; ++i) { |
| this._afterQueue[i].run(); |
| this._afterQueue[i] = void 0; |
| } |
| |
| this._afterQueueLen = 0; |
| }; |
| |
| return Scheduler; |
| |
| }); |
| }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); |