twitst4tz

twitter statistics web application
Log | Files | Refs | README | LICENSE

async.js (2876B)


      1 "use strict";
      2 var firstLineError;
      3 try {throw new Error(); } catch (e) {firstLineError = e;}
      4 var schedule = require("./schedule");
      5 var Queue = require("./queue");
      6 
      7 function Async() {
      8     this._customScheduler = false;
      9     this._isTickUsed = false;
     10     this._lateQueue = new Queue(16);
     11     this._normalQueue = new Queue(16);
     12     this._haveDrainedQueues = false;
     13     var self = this;
     14     this.drainQueues = function () {
     15         self._drainQueues();
     16     };
     17     this._schedule = schedule;
     18 }
     19 
     20 Async.prototype.setScheduler = function(fn) {
     21     var prev = this._schedule;
     22     this._schedule = fn;
     23     this._customScheduler = true;
     24     return prev;
     25 };
     26 
     27 Async.prototype.hasCustomScheduler = function() {
     28     return this._customScheduler;
     29 };
     30 
     31 Async.prototype.haveItemsQueued = function () {
     32     return this._isTickUsed || this._haveDrainedQueues;
     33 };
     34 
     35 
     36 Async.prototype.fatalError = function(e, isNode) {
     37     if (isNode) {
     38         process.stderr.write("Fatal " + (e instanceof Error ? e.stack : e) +
     39             "\n");
     40         process.exit(2);
     41     } else {
     42         this.throwLater(e);
     43     }
     44 };
     45 
     46 Async.prototype.throwLater = function(fn, arg) {
     47     if (arguments.length === 1) {
     48         arg = fn;
     49         fn = function () { throw arg; };
     50     }
     51     if (typeof setTimeout !== "undefined") {
     52         setTimeout(function() {
     53             fn(arg);
     54         }, 0);
     55     } else try {
     56         this._schedule(function() {
     57             fn(arg);
     58         });
     59     } catch (e) {
     60         throw new Error("No async scheduler available\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
     61     }
     62 };
     63 
     64 function AsyncInvokeLater(fn, receiver, arg) {
     65     this._lateQueue.push(fn, receiver, arg);
     66     this._queueTick();
     67 }
     68 
     69 function AsyncInvoke(fn, receiver, arg) {
     70     this._normalQueue.push(fn, receiver, arg);
     71     this._queueTick();
     72 }
     73 
     74 function AsyncSettlePromises(promise) {
     75     this._normalQueue._pushOne(promise);
     76     this._queueTick();
     77 }
     78 
     79 Async.prototype.invokeLater = AsyncInvokeLater;
     80 Async.prototype.invoke = AsyncInvoke;
     81 Async.prototype.settlePromises = AsyncSettlePromises;
     82 
     83 
     84 function _drainQueue(queue) {
     85     while (queue.length() > 0) {
     86         _drainQueueStep(queue);
     87     }
     88 }
     89 
     90 function _drainQueueStep(queue) {
     91     var fn = queue.shift();
     92     if (typeof fn !== "function") {
     93         fn._settlePromises();
     94     } else {
     95         var receiver = queue.shift();
     96         var arg = queue.shift();
     97         fn.call(receiver, arg);
     98     }
     99 }
    100 
    101 Async.prototype._drainQueues = function () {
    102     _drainQueue(this._normalQueue);
    103     this._reset();
    104     this._haveDrainedQueues = true;
    105     _drainQueue(this._lateQueue);
    106 };
    107 
    108 Async.prototype._queueTick = function () {
    109     if (!this._isTickUsed) {
    110         this._isTickUsed = true;
    111         this._schedule(this.drainQueues);
    112     }
    113 };
    114 
    115 Async.prototype._reset = function () {
    116     this._isTickUsed = false;
    117 };
    118 
    119 module.exports = Async;
    120 module.exports.firstLineError = firstLineError;