Recursion is a common trick that is often used in JavaScript programming. So infinite recursion will cause stack overflow errors.
Some languages resolves this issue by introduce automatically tail call optimization, but in JavaScript we need to take care it on our own.
To solve the issue, Node.js
has the utility functions nextTick
to ensure specific code is invoked after the current function returned.
In Browser there is no standard approach to solve this issue, so workarounds are needed.
Thanks to Roman Shtylman(@defunctzombie), who created the node-process
for Browserify
, which simulate the Node.js
API in browser environment.
Here is his implementation:
node-process
Here is some comments on the implementation.
setTimeout
To simulate the nextTick behavior, setTimeout(fn, 0)
is a well-known and easy to adopt approach. The issue of this method is that setTimeout
function does heavy operations, call it in loop causes significant performance issue. So we should try to use cheaper approach when possible.
setImmidate
There is a function called setImmediate
, which behaves quite similar to nextTick
but with a few differences when dealing with IO stuff. But in browser environment, there is no IO issue, so we can definitely replace the nextTick
with it.
Immediates are queued in the order created, and are popped off the queue once per loop iteration. This is different from process.nextTick which will execute process.maxTickDepth queued callbacks per iteration. setImmediate will yield to the event loop after firing a queued callback to make sure I/O is not being starved. While order is preserved for execution, other I/O events may fire between any two scheduled immediate callbacks.
The setImmediate
function is perfect replacement for nextTick
, but it is not supported by all the browsers. Only IE 10
and Node.js 0.10.+
supports it. Chrome, Firefox, Opera and all mobile browsers don’t.
Note: This method is not expected to become standard, and is only implemented by recent builds of Internet Explorer and Node.js 0.10+. It meets resistance both from Gecko (Firefox) and Webkit (Google/Apple).
window.postMessage
window.postMessage
enable developer to access message queue in the browser. By adding some additional code, we can simulate nextTick behavior based on message queue. It works in most modern browser, except IE 8
. In IE 8
, the API is implemented in a synchronous way, which introduce an extra level of stack-push, so it cannot be used to simulate nextTick
.
Overall, there is no perfect workaround to the nextTick
issue for now. All the solutions have different limitations, we can only hope that this issue can be resolved in the future ECMAScript standard.