talles
talles

Reputation: 15096

Common approach to process.nextTick

How often, or when, should I use process.nextTick?

I understand the purpose of it (mainly because of this and this).

As rule of thumb, I'm always using it when I have to call a callback. Is this the general approach or there is more to it?

Also, on here:

It is very important for APIs to be either 100% synchronous or 100% asynchronous.

Being 100% synchronous simply means never using process.nextTick and 100% asynchronous always using it?

Upvotes: 1

Views: 321

Answers (1)

josh3736
josh3736

Reputation: 144912

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`.
    });
};

Upvotes: 1

Related Questions