Q uses process.nextTick instead of setImmediate in Node 0.10.x
I am using Q 1.0.1 and Node.js 0.10.24
I have a application that uses Q to recursively process large amounts of data using the following pattern:
doPromiseyThing()
.then(function(result) {
if (moreToDo) {
return doPromiseyThing();
}
return result;
});If there is a large amount of data to process in this way, I eventually get the error:
Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
node.js:375
throw new Error(msg);
^
Error: (node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
at maxTickWarn (node.js:375:15)
at process.nextTick (node.js:480:9)
at onwrite (_stream_writable.js:260:15)
at WritableState.onwrite (_stream_writable.js:97:5)
at Socket._write (net.js:651:5)
at doWrite (_stream_writable.js:221:10)
at writeOrBuffer (_stream_writable.js:211:5)
at Socket.Writable.write (_stream_writable.js:180:11)
at Socket.write (net.js:613:40)
at Console.warn (console.js:61:16)This error is not caught by my fail handler function, so I cannot recover from it. It comes across as an uncaught exception in Node. However, this is not the point of me creating the ticket.
The error states that setImmediate should be used instead of process.nextTick. Looking at the source of q.js lines 158 - 177:
if (typeof process !== "undefined" && process.nextTick) {
// Node.js before 0.9. Note that some fake-Node environments, like the
// Mocha test runner, introduce a `process` global without a `nextTick`.
isNodeJS = true;
requestTick = function () {
process.nextTick(flush);
};
} else if (typeof setImmediate === "function") {
// In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
if (typeof window !== "undefined") {
requestTick = setImmediate.bind(window, flush);
} else {
requestTick = function () {
setImmediate(flush);
};
}
}It prefers process.nextTick to setImmediate.
If would be nice if this code was changed to use setImmediate, or if I could configure Q to prefer setImmediate over process.nextTick via an environment variable.
Source: kriskowal/q