What is non-blocking or asynchronous I/O in Node.js?
Asked Answered
C

2

154

In the context of Server Side Javascript engines, what is non-blocking I/O or asynchronous I/O? I see this being mentioned as an advantage over Java server side implementations.

Choate answered 13/5, 2012 at 8:13 Comment(1)
It's helpful to think about script tags in the browser environment in order to understand this concept. Zakas has a great article about this - the first few sections should be enough to explain the concept of blocking: nczonline.net/blog/2010/08/10/what-is-a-non-blocking-scriptUitlander
H
356

Synchronous vs Asynchronous

Synchronous execution usually refers to code executing in sequence. Asynchronous execution refers to execution that doesn't run in the sequence it appears in the code. In the following example, the synchronous operation causes the alerts to fire in sequence. In the async operation, while alert(2) appears to execute second, it doesn't.

Synchronous: 1,2,3

alert(1);
alert(2);
alert(3);

Asynchronous: 1,3,2

alert(1);
setTimeout(() => alert(2), 0);
alert(3);

Blocking vs Non-blocking

Blocking refers to operations that block further execution until that operation finishes. Non-blocking refers to code that doesn't block execution. In the given example, localStorage is a blocking operation as it stalls execution to read. On the other hand, fetch is a non-blocking operation as it does not stall alert(3) from execution.

// Blocking: 1,... 2
alert(1);
var value = localStorage.getItem('foo');
alert(2);

// Non-blocking: 1, 3,... 2
alert(1);
fetch('example.com').then(() => alert(2));
alert(3);

Advantages

One advantage of non-blocking, asynchronous operations is that you can maximize the usage of a single CPU as well as memory.

Synchronous, blocking example

An example of synchronous, blocking operations is how some web servers like ones in Java or PHP handle IO or network requests. If your code reads from a file or the database, your code "blocks" everything after it from executing. In that period, your machine is holding onto memory and processing time for a thread that isn't doing anything.

In order to cater other requests while that thread has stalled depends on your software. What most server software do is spawn more threads to cater the additional requests. This requires more memory consumed and more processing.

Asynchronous, non-blocking example

Asynchronous, non-blocking servers - like ones made in Node - only use one thread to service all requests. This means an instance of Node makes the most out of a single thread. The creators designed it with the premise that the I/O and network operations are the bottleneck.

When requests arrive at the server, they are serviced one at a time. However, when the code serviced needs to query the DB for example, it sends the callback to a second queue and the main thread will continue running (it doesn't wait). Now when the DB operation completes and returns, the corresponding callback pulled out of the second queue and queued in a third queue where they are pending execution. When the engine gets a chance to execute something else (like when the execution stack is emptied), it picks up a callback from the third queue and executes it.

Hermosillo answered 13/5, 2012 at 8:14 Comment(16)
I'm not sure I understand your 2nd paragraph under Blocking in PHP. Are you saying that, "While PHP would normally block on IO, it doesn't because the OS automatically threads IO operations."? Or, are you saying that this isn't an issue in PHP because PHP automatically creates a new thread for each request so one blocked request doesn't halt the entire PHP environment? (I'm guessing the latter..)Anaphylaxis
wait, if it's mean the latter one, what the advantages non blocking I/O PHP (like reactPHP or something else) over the blocking one. still confuseCharkha
@SunuPinasthikaFajar PHP alone is synchronous, but the server software allows it to thread per request, thus making it look like a request is not blocking another. React allows PHP alone to run in an asynchronous manner.Hermosillo
ok, got it. the server software make it happen :). thanks. in other words, because the server software create thread per request, server will consume more resource like ram or CPU, right?Charkha
@JosephtheDreamer When you say "I (NodeJS) will come back to you when you (IO operation) are done. For the meantime, I'll be doing something else.", does that mean in node.js, when code is running, does that mean that the io operation is run the the background in parallel with your javascript code? Or when is the asynchronous function actually called?Refurbish
@CharlieParker Yes. The async operation runs parallel to your code. But the callback that "gets back" to the results of the async operation are queued for execution in the main code when the main code isn't busy.Hermosillo
The thing that I find confusing is that I normally hear that "node.js only has one thread". If that is true then how come the io is being done in parallel? If its running in parallel I am assuming that then that is taken care of by the Operating System. Right? Btw, Thnx! :)Refurbish
@CharlieParker Here's a post that deals more about the internals of the async mechanism.Hermosillo
Is "nonblocking" the same as "asynchronous blocking"? In the article "The C10K Problem" kegel.com/c10k.html, the author seems to refer to two different things. For example, in this sentence: "This has not yet become popular in Unix, probably because few operating systems support asynchronous I/O, also possibly because it (like nonblocking I/O) requires rethinking your application." He seems to refer the two to two different things.Least
@Least Here's 2 posts dicsussing that: https://mcmap.net/q/74175/-asynchronous-and-non-blocking-calls-also-between-blocking-and-synchronous/575527 and https://mcmap.net/q/75454/-what-39-s-the-difference-between-asynchronous-non-blocking-event-base-architectures/575527. In the context of NodeJS, it's async in a sense that you run something in the background, and a callback is called (message back). It's non-blocking in a sense that it doesn't stall the thread. In JS, operations in both definitions hence used interchangeably.Hermosillo
@Hermosillo the Dreamer In the article "The C10K Problem" kegel.com/c10k.html, the author talks about the server. NodeJS is a server. So I guess the author talks about the two different things. Could you have a look at the article and make some comments?Least
you said Now when the DB operation completes and returns, the corresponding callback pulled out of the second queue, but how this magical thing works exactly ? Is there a link between the callback (in the queue 2) and the process responsible for querying the DB ?America
@OlivierBoissé You can search the internet for "JS event loop" or watch this video.Hermosillo
I already saw it, I understood the concept, but I want to go deeper. I am wondering how the program knows that the DB operation is completed and so it has to call the callback. From what I read on the internet, Non-blocking IO works with channels, a thread can read/write piece of data in channels without blocking IO for the rest of the dataAmerica
@OlivierBoissé That's engine implementation, beyond the scope of this question. You can always post a question specifically asking for just that.Hermosillo
@Hermosillo Is (non)blocking the same thing as (a)synchronous? First you give different definitions for each, but later you use them as synonyms.Marguerita
M
12
var startTime = new Date().getTime();
var getEndTime = () => {
    var tempEndTime = new Date().getTime();
    var second = (tempEndTime - startTime)/1000
    return `took ${second} sec...to finish\n`
}

console.log('1: start App', getEndTime())
setTimeout(()=>{
    console.log('2: setTimeout', getEndTime())
}, 1000)
console.log('3: End App', getEndTime())

// console -> Process Order:  1 -> 3 -> 2

Code example

Mitinger answered 31/8, 2016 at 16:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.