From 1ee6cd7a1f5580fa58f4467d29cb8933a663b9af Mon Sep 17 00:00:00 2001 From: Bruno Jouhier Date: Fri, 28 Nov 2014 17:10:39 +0100 Subject: [PATCH] fixed #252 - setImmediate not available in browsers --- lib/callbacks/flows.js | 29 ++++++++++++++++++----------- lib/compiler/flows._js | 21 ++++++++++++++------- lib/fibers-fast/flows.js | 21 ++++++++++++++------- lib/fibers/flows.js | 29 ++++++++++++++++++----------- lib/generators-fast/flows.js | 21 ++++++++++++++------- lib/generators/flows.js | 21 ++++++++++++++------- lib/transform-all.js | 4 +++- lib/util/flows.md | 3 +++ 8 files changed, 98 insertions(+), 51 deletions(-) diff --git a/lib/callbacks/flows.js b/lib/callbacks/flows.js index fb75f15e..3a114cd2 100644 --- a/lib/callbacks/flows.js +++ b/lib/callbacks/flows.js @@ -178,13 +178,13 @@ return { wait: __rt.streamlinify(function(cb) { if (callback) { throw new Error("already waiting") }; - if (notified) { setImmediate(cb); } else { + if (notified) { exports.setImmediate(cb); } else { callback = cb; }; notified = false; }, 0), notify: function() { if (!callback) { notified = true; } else { - setImmediate(callback); }; + exports.setImmediate(callback); }; callback = null; } }; }; @@ -210,12 +210,12 @@ var item = q.shift(); if ((q.length === 0)) { q = []; }; - setImmediate(function() { + exports.setImmediate(function() { cb(null, item); }); if ((pendingWrites.length > 0)) { var wr = pendingWrites.shift(); - setImmediate(function() { + exports.setImmediate(function() { wr[0](null, wr[1]); }); } ; } @@ -225,7 +225,7 @@ }, 0), write: __rt.streamlinify(function(cb, item) { if (this.put(item)) { - setImmediate(function() { + exports.setImmediate(function() { cb(); }); } else { @@ -239,7 +239,7 @@ else { var cb = callback; callback = null; - setImmediate(function() { + exports.setImmediate(function() { cb(null, item); }); } ; @@ -280,7 +280,7 @@ exports.trampoline = __rt.streamlinify(function(cb, fn, thisObj) { fn = globals.withContext(fn, globals.context); - setImmediate(function() { + exports.setImmediate(function() { fn.call(thisObj, cb); }); }, 0); @@ -288,13 +288,20 @@ + exports.setImmediate = ((typeof setImmediate === "function") ? setImmediate : function(fn) { + setTimeout(fn, 0); }); + + + + + var nextTick = (((typeof process === "object") && (typeof process.nextTick === "function")) ? process.nextTick : function(cb) { cb(); }); - exports.nextTick = function exports_nextTick__11(_) { var __frame = { name: "exports_nextTick__11", line: 297 }; return __func(_, this, arguments, exports_nextTick__11, 0, __frame, function __$exports_nextTick__11() { + exports.nextTick = function exports_nextTick__11(_) { var __frame = { name: "exports_nextTick__11", line: 304 }; return __func(_, this, arguments, exports_nextTick__11, 0, __frame, function __$exports_nextTick__11() { return nextTick(__cb(_, __frame, 1, 2, function __$exports_nextTick__11() { _(); }, true)); }); }; @@ -326,7 +333,7 @@ - exports.sleep = function exports_sleep__12(_, millis) { var __frame = { name: "exports_sleep__12", line: 329 }; return __func(_, this, arguments, exports_sleep__12, 0, __frame, function __$exports_sleep__12() { + exports.sleep = function exports_sleep__12(_, millis) { var __frame = { name: "exports_sleep__12", line: 336 }; return __func(_, this, arguments, exports_sleep__12, 0, __frame, function __$exports_sleep__12() { return setTimeout(__cb(_, __frame, 1, 9, _, true), millis); }); }; @@ -334,7 +341,7 @@ return function() { var that = this; var args = Array.prototype.slice(arguments, 0); - return (function __1(_) { var __frame = { name: "__1", line: 337 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() { + return (function __1(_) { var __frame = { name: "__1", line: 344 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() { return fn.apply_(__cb(_, __frame, 1, 14, _, true), that, args, 0); }); })(function(err) { if (err) { throw err }; }); }; }; @@ -343,7 +350,7 @@ - exports.apply = function apply(_, fn, thisObj, args, index) { var __frame = { name: "apply", line: 346 }; return __func(_, this, arguments, apply, 0, __frame, function __$apply() { + exports.apply = function apply(_, fn, thisObj, args, index) { var __frame = { name: "apply", line: 353 }; return __func(_, this, arguments, apply, 0, __frame, function __$apply() { return fn.apply_(__cb(_, __frame, 1, 12, _, true), thisObj, args, index); }); }; diff --git a/lib/compiler/flows._js b/lib/compiler/flows._js index def4d8d7..2dfba037 100644 --- a/lib/compiler/flows._js +++ b/lib/compiler/flows._js @@ -178,13 +178,13 @@ return { wait: _(function(cb) { if (callback) throw new Error("already waiting"); - if (notified) setImmediate(cb); + if (notified) exports.setImmediate(cb); else callback = cb; notified = false; }, 0), notify: function() { if (!callback) notified = true; - else setImmediate(callback); + else exports.setImmediate(callback); callback = null; }, }; @@ -210,12 +210,12 @@ var item = q.shift(); // recycle queue when empty to avoid maintaining arrays that have grown large and shrunk if (q.length === 0) q = []; - setImmediate(function() { + exports.setImmediate(function() { cb(null, item); }); if (pendingWrites.length > 0) { var wr = pendingWrites.shift(); - setImmediate(function() { + exports.setImmediate(function() { wr[0](null, wr[1]); }); } @@ -225,7 +225,7 @@ }, 0), write: _(function(cb, item) { if (this.put(item)) { - setImmediate(function() { + exports.setImmediate(function() { cb(); }); } else { @@ -239,7 +239,7 @@ } else { var cb = callback; callback = null; - setImmediate(function() { + exports.setImmediate(function() { cb(null, item); }); } @@ -280,11 +280,18 @@ /// before calling `fn`. exports.trampoline = _(function(cb, fn, thisObj) { fn = globals.withContext(fn, globals.context); - setImmediate(function() { + exports.setImmediate(function() { fn.call(thisObj, _ >> cb); }); }, 0); + /// + /// * `flows.setImmediate(fn)` + /// portable `setImmediate` both browser and server. + exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) { + setTimeout(fn, 0); + }; + /// /// * `flows.nextTick(_)` /// `nextTick` function for both browser and server. diff --git a/lib/fibers-fast/flows.js b/lib/fibers-fast/flows.js index 7b715e7a..e82b976b 100644 --- a/lib/fibers-fast/flows.js +++ b/lib/fibers-fast/flows.js @@ -178,13 +178,13 @@ return { wait: fstreamline__.star(function(cb) { if (callback) throw new Error("already waiting"); - if (notified) setImmediate(cb); + if (notified) exports.setImmediate(cb); else callback = cb; notified = false; }, 0), notify: function() { if (!callback) notified = true; - else setImmediate(callback); + else exports.setImmediate(callback); callback = null; }, }; @@ -210,12 +210,12 @@ var item = q.shift(); // recycle queue when empty to avoid maintaining arrays that have grown large and shrunk if (q.length === 0) q = []; - setImmediate(function() { + exports.setImmediate(function() { cb(null, item); }); if (pendingWrites.length > 0) { var wr = pendingWrites.shift(); - setImmediate(function() { + exports.setImmediate(function() { wr[0](null, wr[1]); }); } @@ -225,7 +225,7 @@ }, 0), write: fstreamline__.star(function(cb, item) { if (this.put(item)) { - setImmediate(function() { + exports.setImmediate(function() { cb(); }); } else { @@ -239,7 +239,7 @@ } else { var cb = callback; callback = null; - setImmediate(function() { + exports.setImmediate(function() { cb(null, item); }); } @@ -280,11 +280,18 @@ /// before calling `fn`. exports.trampoline = fstreamline__.star(function(cb, fn, thisObj) { fn = globals.withContext(fn, globals.context); - setImmediate(function() { + exports.setImmediate(function() { fstreamline__.createBound(fn,'call',1)(thisObj, cb); }); }, 0); + /// + /// * `flows.setImmediate(fn)` + /// portable `setImmediate` both browser and server. + exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) { + setTimeout(fn, 0); + }; + /// /// * `flows.nextTick(_)` /// `nextTick` function for both browser and server. diff --git a/lib/fibers/flows.js b/lib/fibers/flows.js index b93a7cfe..049a2637 100644 --- a/lib/fibers/flows.js +++ b/lib/fibers/flows.js @@ -178,13 +178,13 @@ return { wait: fstreamline__.streamlinify(function(cb) { if (callback) throw new Error("already waiting"); - if (notified) setImmediate(cb); + if (notified) exports.setImmediate(cb); else callback = cb; notified = false; }, 0), notify: function() { if (!callback) notified = true; - else setImmediate(callback); + else exports.setImmediate(callback); callback = null; }, }; @@ -210,12 +210,12 @@ var item = q.shift(); // recycle queue when empty to avoid maintaining arrays that have grown large and shrunk if (q.length === 0) q = []; - setImmediate(function() { + exports.setImmediate(function() { cb(null, item); }); if (pendingWrites.length > 0) { var wr = pendingWrites.shift(); - setImmediate(function() { + exports.setImmediate(function() { wr[0](null, wr[1]); }); } @@ -225,7 +225,7 @@ }, 0), write: fstreamline__.streamlinify(function(cb, item) { if (this.put(item)) { - setImmediate(function() { + exports.setImmediate(function() { cb(); }); } else { @@ -239,7 +239,7 @@ } else { var cb = callback; callback = null; - setImmediate(function() { + exports.setImmediate(function() { cb(null, item); }); } @@ -280,11 +280,18 @@ /// before calling `fn`. exports.trampoline = fstreamline__.streamlinify(function(cb, fn, thisObj) { fn = globals.withContext(fn, globals.context); - setImmediate(function() { + exports.setImmediate(function() { fn.call(thisObj, cb); }); }, 0); + /// + /// * `flows.setImmediate(fn)` + /// portable `setImmediate` both browser and server. + exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) { + setTimeout(fn, 0); + }; + /// /// * `flows.nextTick(_)` /// `nextTick` function for both browser and server. @@ -296,7 +303,7 @@ // document later exports.nextTick = fstreamline__.create(function(_) { fstreamline__.invoke(null, nextTick, [_], 0); - }, 0,__filename,297); + }, 0,__filename,304); // document later // should probably cap millis instead of trying to be too smart @@ -328,7 +335,7 @@ /// Sleeps `millis` ms. exports.sleep = fstreamline__.create(function(_, millis) { return fstreamline__.invoke(null, setTimeout, [_, millis], 0); - }, 0,__filename,329); + }, 0,__filename,336); exports.eventHandler = function(fn) { return function() { @@ -336,7 +343,7 @@ var args = Array.prototype.slice(arguments, 0); return fstreamline__.create((function(_) { return fstreamline__.invoke(fn, "apply_", [_, that, args, 0], 0); - }), 0,__filename,337)( function(err) { + }), 0,__filename,344)( function(err) { if (err) throw err; }); }; @@ -345,7 +352,7 @@ // Obsolete. Use `fn.apply_` instead. exports.apply = fstreamline__.create(function apply(_, fn, thisObj, args, index) { return fstreamline__.invoke(fn, "apply_", [_, thisObj, args, index], 0); - }, 0,__filename,346); + }, 0,__filename,353); /// /// * `flows.callWithTimeout(_, fn, millis)` diff --git a/lib/generators-fast/flows.js b/lib/generators-fast/flows.js index 9b08f718..991488c9 100644 --- a/lib/generators-fast/flows.js +++ b/lib/generators-fast/flows.js @@ -178,13 +178,13 @@ return { wait: galaxy.star(function(cb) { if (callback) throw new Error("already waiting"); - if (notified) setImmediate(cb); + if (notified) exports.setImmediate(cb); else callback = cb; notified = false; }, 0), notify: function() { if (!callback) notified = true; - else setImmediate(callback); + else exports.setImmediate(callback); callback = null; }, }; @@ -210,12 +210,12 @@ var item = q.shift(); // recycle queue when empty to avoid maintaining arrays that have grown large and shrunk if (q.length === 0) q = []; - setImmediate(function() { + exports.setImmediate(function() { cb(null, item); }); if (pendingWrites.length > 0) { var wr = pendingWrites.shift(); - setImmediate(function() { + exports.setImmediate(function() { wr[0](null, wr[1]); }); } @@ -225,7 +225,7 @@ }, 0), write: galaxy.star(function(cb, item) { if (this.put(item)) { - setImmediate(function() { + exports.setImmediate(function() { cb(); }); } else { @@ -239,7 +239,7 @@ } else { var cb = callback; callback = null; - setImmediate(function() { + exports.setImmediate(function() { cb(null, item); }); } @@ -280,11 +280,18 @@ /// before calling `fn`. exports.trampoline = galaxy.star(function(cb, fn, thisObj) { fn = globals.withContext(fn, globals.context); - setImmediate(function() { + exports.setImmediate(function() { galaxy.unstarBound(fn,'call',1)(thisObj, cb); }); }, 0); + /// + /// * `flows.setImmediate(fn)` + /// portable `setImmediate` both browser and server. + exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) { + setTimeout(fn, 0); + }; + /// /// * `flows.nextTick(_)` /// `nextTick` function for both browser and server. diff --git a/lib/generators/flows.js b/lib/generators/flows.js index 78fb9a3a..69b6b0ca 100644 --- a/lib/generators/flows.js +++ b/lib/generators/flows.js @@ -178,13 +178,13 @@ return { wait: galaxy.streamlinify(function(cb) { if (callback) throw new Error("already waiting"); - if (notified) setImmediate(cb); + if (notified) exports.setImmediate(cb); else callback = cb; notified = false; }, 0), notify: function() { if (!callback) notified = true; - else setImmediate(callback); + else exports.setImmediate(callback); callback = null; }, }; @@ -210,12 +210,12 @@ var item = q.shift(); // recycle queue when empty to avoid maintaining arrays that have grown large and shrunk if (q.length === 0) q = []; - setImmediate(function() { + exports.setImmediate(function() { cb(null, item); }); if (pendingWrites.length > 0) { var wr = pendingWrites.shift(); - setImmediate(function() { + exports.setImmediate(function() { wr[0](null, wr[1]); }); } @@ -225,7 +225,7 @@ }, 0), write: galaxy.streamlinify(function(cb, item) { if (this.put(item)) { - setImmediate(function() { + exports.setImmediate(function() { cb(); }); } else { @@ -239,7 +239,7 @@ } else { var cb = callback; callback = null; - setImmediate(function() { + exports.setImmediate(function() { cb(null, item); }); } @@ -280,11 +280,18 @@ /// before calling `fn`. exports.trampoline = galaxy.streamlinify(function(cb, fn, thisObj) { fn = globals.withContext(fn, globals.context); - setImmediate(function() { + exports.setImmediate(function() { fn.call(thisObj, cb); }); }, 0); + /// + /// * `flows.setImmediate(fn)` + /// portable `setImmediate` both browser and server. + exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) { + setTimeout(fn, 0); + }; + /// /// * `flows.nextTick(_)` /// `nextTick` function for both browser and server. diff --git a/lib/transform-all.js b/lib/transform-all.js index 13c314f1..b87ea9ad 100644 --- a/lib/transform-all.js +++ b/lib/transform-all.js @@ -4313,8 +4313,10 @@ if (typeof exports !== 'undefined') { // }).apply(this, args); var indexes = []; var paramI = -1; + var skip = 0; for (var i = 0; i < node.body.children.length; i++) { var child = node.body.children[i]; + if (i === 0 && child.type === VAR) { skip = 1; continue; } if (child.type !== IF) return false; if (child.condition.type !== EQ) return false; var ident = child.condition.children[0]; @@ -4343,7 +4345,7 @@ if (typeof exports !== 'undefined') { node.params[paramI] = cb; for (var k = 0; k < indexes.length; k++) { // chain has been verified above - var ifn = node.body.children[k]; + var ifn = node.body.children[skip + k]; if (k === indexes.length - 1) ifn.condition.children[0].value = cb; var lhs = ifn.thenPart.children[0].expression.children[0]; // too lazy to create real tree - fake it with identifier diff --git a/lib/util/flows.md b/lib/util/flows.md index 413035bf..63769571 100644 --- a/lib/util/flows.md +++ b/lib/util/flows.md @@ -55,6 +55,9 @@ won't be called, and no other operation will enter the funnel. This is equivalent to calling `fn.call(thisObj, _)` but the current stack is unwound before calling `fn`. +* `flows.setImmediate(fn)` + portable `setImmediate` both browser and server. + * `flows.nextTick(_)` `nextTick` function for both browser and server. Aliased to `process.nextTick` on the server side.