You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					121 lines
				
				2.8 KiB
			
		
		
			
		
	
	
					121 lines
				
				2.8 KiB
			| 
											3 years ago
										 | "use strict"; | ||
|  | 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; |