Spaces:
Paused
Paused
| ; | |
| var firstLineError; | |
| try {throw new Error(); } catch (e) {firstLineError = e;} | |
| var schedule = require("./schedule"); | |
| var Queue = require("./queue"); | |
| function Async() { | |
| this._customScheduler = false; | |
| this._isTickUsed = false; | |
| this._lateQueue = new Queue(16); | |
| this._normalQueue = new Queue(16); | |
| this._haveDrainedQueues = false; | |
| var self = this; | |
| this.drainQueues = function () { | |
| self._drainQueues(); | |
| }; | |
| this._schedule = schedule; | |
| } | |
| Async.prototype.setScheduler = function(fn) { | |
| var prev = this._schedule; | |
| this._schedule = fn; | |
| this._customScheduler = true; | |
| return prev; | |
| }; | |
| Async.prototype.hasCustomScheduler = function() { | |
| return this._customScheduler; | |
| }; | |
| Async.prototype.haveItemsQueued = function () { | |
| return this._isTickUsed || this._haveDrainedQueues; | |
| }; | |
| Async.prototype.fatalError = function(e, isNode) { | |
| if (isNode) { | |
| process.stderr.write("Fatal " + (e instanceof Error ? e.stack : e) + | |
| "\n"); | |
| process.exit(2); | |
| } else { | |
| this.throwLater(e); | |
| } | |
| }; | |
| Async.prototype.throwLater = function(fn, arg) { | |
| if (arguments.length === 1) { | |
| arg = fn; | |
| fn = function () { throw arg; }; | |
| } | |
| if (typeof setTimeout !== "undefined") { | |
| setTimeout(function() { | |
| fn(arg); | |
| }, 0); | |
| } else try { | |
| this._schedule(function() { | |
| fn(arg); | |
| }); | |
| } catch (e) { | |
| throw new Error("No async scheduler available\u000a\u000a See http://goo.gl/MqrFmX\u000a"); | |
| } | |
| }; | |
| function AsyncInvokeLater(fn, receiver, arg) { | |
| this._lateQueue.push(fn, receiver, arg); | |
| this._queueTick(); | |
| } | |
| function AsyncInvoke(fn, receiver, arg) { | |
| this._normalQueue.push(fn, receiver, arg); | |
| this._queueTick(); | |
| } | |
| function AsyncSettlePromises(promise) { | |
| this._normalQueue._pushOne(promise); | |
| this._queueTick(); | |
| } | |
| Async.prototype.invokeLater = AsyncInvokeLater; | |
| Async.prototype.invoke = AsyncInvoke; | |
| Async.prototype.settlePromises = AsyncSettlePromises; | |
| function _drainQueue(queue) { | |
| while (queue.length() > 0) { | |
| _drainQueueStep(queue); | |
| } | |
| } | |
| function _drainQueueStep(queue) { | |
| var fn = queue.shift(); | |
| if (typeof fn !== "function") { | |
| fn._settlePromises(); | |
| } else { | |
| var receiver = queue.shift(); | |
| var arg = queue.shift(); | |
| fn.call(receiver, arg); | |
| } | |
| } | |
| Async.prototype._drainQueues = function () { | |
| _drainQueue(this._normalQueue); | |
| this._reset(); | |
| this._haveDrainedQueues = true; | |
| _drainQueue(this._lateQueue); | |
| }; | |
| Async.prototype._queueTick = function () { | |
| if (!this._isTickUsed) { | |
| this._isTickUsed = true; | |
| this._schedule(this.drainQueues); | |
| } | |
| }; | |
| Async.prototype._reset = function () { | |
| this._isTickUsed = false; | |
| }; | |
| module.exports = Async; | |
| module.exports.firstLineError = firstLineError; | |