Consider the following:
// API:
function foo(bar, cb) {
if (bar) cb();
else {
process.nextTick(cb);
}
}
// User code:
function A(bar) {
var i;
foo(bar, function() {
console.log(i);
});
i = 1;
}
Calling A(true)
prints undefined, while calling A(false)
prints 1.
This is a somewhat contrived example – obviously it's a little silly to assign to i
after we make the async call – but there are real-world scenarios where invoking callback code before the remainder of the calling code can complete might result in subtle bugs.
Thus the recommendation to use nextTick
when you'd otherwise invoke the callback synchronously. Basically, any time you call the user callback in the same stack that your function was called (in other words, if you call the user callback outside of a callback function of your own), use nextTick
.
Here's a more concrete example:
// API
var cache;
exports.getData = function(cb) {
if (cache) process.nextTick(function() {
cb(null, cache); // Here we must use `nextTick` because calling `cb`
// directly would mean that the callback code would
// run BEFORE the rest of the caller's code runs.
});
else db.query(..., function(err, result) {
if (err) return cb(err);
cache = result;
cb(null, result); // Here it it safe to call `cb` directly because
// the db query itself is async; there's no need
// to use `nextTick`.
});
};