11

I'm working on learning Node.js and all I hear in every tutorial is "Node is asynchronous and no -blocking!"

I've heard in regular browser JavaScript only certain things such as AJAX calls can be made asynchronous or non-blocking (using callbacks)... Is this true of Node.js as well, or are all Node.js callback functions made asynchronous/non-blocking?

4
  • 1
    yes. this is the nature of javascript not node.js specific. Commented Feb 19, 2014 at 15:03
  • 7
    @zsong That isn't entirely accurate. Commented Feb 19, 2014 at 15:21
  • 1
    that is totally not accurate. read the spec. nothing about sync/async or blocking/non-blocking or io at all Commented Feb 19, 2014 at 15:24
  • 1
    It isn't the callback that's asynchronous. It's the function you're passing the callback to that's asynchronous, and therefore requires a callback. And not every function that takes a callback does so because it's going to do something async. Commented Feb 19, 2014 at 15:41

3 Answers 3

18

are all Node.js callback functions made asynchronous/non-blocking?

No. Only I/O is usually asynchronous, but many other callbacks are synchronous. Always check the docs.

Examples of async functions:

  • Async Filesystem access (they have sync counterparts without callbacks, though)
  • Timers (setTimeout)
  • process.nextTick, setImmediate
  • most database connections
  • network connections
  • Promises

Examples of sync callbacks:

See also Are all javascript callbacks asynchronous? If not, how do I know which are? (including some other examples).

Sign up to request clarification or add additional context in comments.

10 Comments

That isn't entirely accurate. You're right that I/O is multithreaded and the rest isnt, but many other callbacks are still asynchronous and called in a separate call stack.
What other callbacks do you mean?
@vkurchatkin: They're still callbacks, aren't them?
@vkurchatkin: A function passed to another function for that other function to invoke is a callback. Doesn't matter if the callback will be invoked synchronously or asynchronously. The ECMAScript spec refers to the function passed to .forEach() for example as a "callback".
@Bergi I'm just talking about "other asynchronous callbacks" from Brad's comment, I agree about that part of your answer. To stop off-topic here is an interesting post by isaacs: blog.izs.me/post/59142742143/designing-apis-for-asynchrony here talks more about consistency (always sync or always async), but still relevant
|
4

When you pass a callback to a function, you expect that function to call your callback function some other time. However, it isn't automatically asynchronous.

Suppose I have this code:

function callSomething(callback) {
  callback();
}

function theCallback() {
  // Do something time consuming here
}

callSomething(theCallback);

In this case, we're passing a callback, but the callback gets called immediately on the existing call stack. This is considered bad practice and is strongly discouraged in Node.js. If you want to call a callback fairly immediately, use process.nextTick():

function callSomething(callback) {
  process.nextTick(callback);
}

So the direct answer to your question is mostly yes. When you specify a callback to functions in Node.js, by convention they will be called on another callstack at a later point in time. But if you are using some bad code from someone who didn't know how to follow this convention, there is no guarantee.

2 Comments

True in general. Also worth mentioning that setImmediate could be used and I've heard couple of node core members saying that it's better to use it than nextTick to avoid nextTick specific problems (IO starvation mostly)
@vkurchatkin Interesting, I hadn't heard of setImmediate. I'm definitely swapping this out in some of my projects! stackoverflow.com/a/15349865/362536
2

Nope, they are not automatically asynchronous. Consider this code:

function foo(array, filter, callback) {
    var result = []
    for (var i = 0; i < array.length; i++) {
        if (filter(array[i])) result.push(array[i]);
    }

    callback(result);
}

And now imagine a program like this:

foo([ 1, 2, 3, 4 ], function() { while(true); }, console.log);
console.log('Blocking?');

If foo would be asynchronous then Blocking? would immediatly appear, but it does not!


You can be pretty sure, however, that most / all of the standard library taking a callback is non-blocking async code. Most of it also has a Sync counterpart.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.