3 try {throw new Error(); } catch (e) {firstLineError = e;}
4 var schedule = require("./schedule");
5 var Queue = require("./queue");
6 var util = require("./util");
9 this._isTickUsed = false;
10 this._lateQueue = new Queue(16);
11 this._normalQueue = new Queue(16);
12 this._haveDrainedQueues = false;
13 this._trampolineEnabled = true;
15 this.drainQueues = function () {
18 this._schedule = schedule;
21 Async.prototype.enableTrampoline = function() {
22 this._trampolineEnabled = true;
25 Async.prototype.disableTrampolineIfNecessary = function() {
26 if (util.hasDevTools) {
27 this._trampolineEnabled = false;
31 Async.prototype.haveItemsQueued = function () {
32 return this._isTickUsed || this._haveDrainedQueues;
36 Async.prototype.fatalError = function(e, isNode) {
38 process.stderr.write("Fatal " + (e instanceof Error ? e.stack : e));
45 Async.prototype.throwLater = function(fn, arg) {
46 if (arguments.length === 1) {
48 fn = function () { throw arg; };
50 if (typeof setTimeout !== "undefined") {
51 setTimeout(function() {
55 this._schedule(function() {
59 throw new Error("No async scheduler available\u000a\u000a See http://goo.gl/MqrFmX\u000a");
63 function AsyncInvokeLater(fn, receiver, arg) {
64 this._lateQueue.push(fn, receiver, arg);
68 function AsyncInvoke(fn, receiver, arg) {
69 this._normalQueue.push(fn, receiver, arg);
73 function AsyncSettlePromises(promise) {
74 this._normalQueue._pushOne(promise);
78 if (!util.hasDevTools) {
79 Async.prototype.invokeLater = AsyncInvokeLater;
80 Async.prototype.invoke = AsyncInvoke;
81 Async.prototype.settlePromises = AsyncSettlePromises;
83 Async.prototype.invokeLater = function (fn, receiver, arg) {
84 if (this._trampolineEnabled) {
85 AsyncInvokeLater.call(this, fn, receiver, arg);
87 this._schedule(function() {
88 setTimeout(function() {
89 fn.call(receiver, arg);
95 Async.prototype.invoke = function (fn, receiver, arg) {
96 if (this._trampolineEnabled) {
97 AsyncInvoke.call(this, fn, receiver, arg);
99 this._schedule(function() {
100 fn.call(receiver, arg);
105 Async.prototype.settlePromises = function(promise) {
106 if (this._trampolineEnabled) {
107 AsyncSettlePromises.call(this, promise);
109 this._schedule(function() {
110 promise._settlePromises();
116 Async.prototype.invokeFirst = function (fn, receiver, arg) {
117 this._normalQueue.unshift(fn, receiver, arg);
121 Async.prototype._drainQueue = function(queue) {
122 while (queue.length() > 0) {
123 var fn = queue.shift();
124 if (typeof fn !== "function") {
125 fn._settlePromises();
128 var receiver = queue.shift();
129 var arg = queue.shift();
130 fn.call(receiver, arg);
134 Async.prototype._drainQueues = function () {
135 this._drainQueue(this._normalQueue);
137 this._haveDrainedQueues = true;
138 this._drainQueue(this._lateQueue);
141 Async.prototype._queueTick = function () {
142 if (!this._isTickUsed) {
143 this._isTickUsed = true;
144 this._schedule(this.drainQueues);
148 Async.prototype._reset = function () {
149 this._isTickUsed = false;
152 module.exports = Async;
153 module.exports.firstLineError = firstLineError;