Version 1
[yaffs-website] / node_modules / bluebird / js / release / async.js
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 var util = require("./util");
7
8 function Async() {
9     this._isTickUsed = false;
10     this._lateQueue = new Queue(16);
11     this._normalQueue = new Queue(16);
12     this._haveDrainedQueues = false;
13     this._trampolineEnabled = true;
14     var self = this;
15     this.drainQueues = function () {
16         self._drainQueues();
17     };
18     this._schedule = schedule;
19 }
20
21 Async.prototype.enableTrampoline = function() {
22     this._trampolineEnabled = true;
23 };
24
25 Async.prototype.disableTrampolineIfNecessary = function() {
26     if (util.hasDevTools) {
27         this._trampolineEnabled = false;
28     }
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         process.exit(2);
40     } else {
41         this.throwLater(e);
42     }
43 };
44
45 Async.prototype.throwLater = function(fn, arg) {
46     if (arguments.length === 1) {
47         arg = fn;
48         fn = function () { throw arg; };
49     }
50     if (typeof setTimeout !== "undefined") {
51         setTimeout(function() {
52             fn(arg);
53         }, 0);
54     } else try {
55         this._schedule(function() {
56             fn(arg);
57         });
58     } catch (e) {
59         throw new Error("No async scheduler available\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
60     }
61 };
62
63 function AsyncInvokeLater(fn, receiver, arg) {
64     this._lateQueue.push(fn, receiver, arg);
65     this._queueTick();
66 }
67
68 function AsyncInvoke(fn, receiver, arg) {
69     this._normalQueue.push(fn, receiver, arg);
70     this._queueTick();
71 }
72
73 function AsyncSettlePromises(promise) {
74     this._normalQueue._pushOne(promise);
75     this._queueTick();
76 }
77
78 if (!util.hasDevTools) {
79     Async.prototype.invokeLater = AsyncInvokeLater;
80     Async.prototype.invoke = AsyncInvoke;
81     Async.prototype.settlePromises = AsyncSettlePromises;
82 } else {
83     Async.prototype.invokeLater = function (fn, receiver, arg) {
84         if (this._trampolineEnabled) {
85             AsyncInvokeLater.call(this, fn, receiver, arg);
86         } else {
87             this._schedule(function() {
88                 setTimeout(function() {
89                     fn.call(receiver, arg);
90                 }, 100);
91             });
92         }
93     };
94
95     Async.prototype.invoke = function (fn, receiver, arg) {
96         if (this._trampolineEnabled) {
97             AsyncInvoke.call(this, fn, receiver, arg);
98         } else {
99             this._schedule(function() {
100                 fn.call(receiver, arg);
101             });
102         }
103     };
104
105     Async.prototype.settlePromises = function(promise) {
106         if (this._trampolineEnabled) {
107             AsyncSettlePromises.call(this, promise);
108         } else {
109             this._schedule(function() {
110                 promise._settlePromises();
111             });
112         }
113     };
114 }
115
116 Async.prototype.invokeFirst = function (fn, receiver, arg) {
117     this._normalQueue.unshift(fn, receiver, arg);
118     this._queueTick();
119 };
120
121 Async.prototype._drainQueue = function(queue) {
122     while (queue.length() > 0) {
123         var fn = queue.shift();
124         if (typeof fn !== "function") {
125             fn._settlePromises();
126             continue;
127         }
128         var receiver = queue.shift();
129         var arg = queue.shift();
130         fn.call(receiver, arg);
131     }
132 };
133
134 Async.prototype._drainQueues = function () {
135     this._drainQueue(this._normalQueue);
136     this._reset();
137     this._haveDrainedQueues = true;
138     this._drainQueue(this._lateQueue);
139 };
140
141 Async.prototype._queueTick = function () {
142     if (!this._isTickUsed) {
143         this._isTickUsed = true;
144         this._schedule(this.drainQueues);
145     }
146 };
147
148 Async.prototype._reset = function () {
149     this._isTickUsed = false;
150 };
151
152 module.exports = Async;
153 module.exports.firstLineError = firstLineError;