Search code examples
node.jsasynchronousblockingnonblockingsynchronous

nodejs is asynchronous/synchronous process, nonblocking/bloking IO


What is asynchronous process in nodejs?. Take a look at my testing.

+ Person.find(): query on database, it will take time
+ while(): delay for 5s

And the result in console like this serial:

the first:  Listening on port 3000
the second: Wait
----third:  0
---------:  4
---------:  2
---------:  2
---------:  3
---------:  1
---------:  1

If we talk this is asynchronous process, why the program stop at while() function in 5s before run console.log('0') and console.log ('4')?

var Product = mongoose.model('Product', ProductSchema);
var myObject = new Object();

Person.find().exec(function (err, docs) {

    for (var i=0;i<docs.length;i++)
    { 
        Product.find({ user: docs[i]._id},function (err, pers) {
             myObject[i] = pers;
             console.log('1'); 
            });
        console.log('2'); 
    }
    console.log('3'); 
});
console.log('Listening on port 3000'); 
var startTime = new Date().getTime();
console.log('wait');
while (new Date().getTime() < startTime + 5000); //the program stop here for 5s before priting 
console.log('0');                                //console.log('0') and console.log('4');

app.listen(3000);
console.log('4');

Solution

  • The reason you're getting this order of execution is because the only asynchronous functions you're showing are Person.find().exec() and Product.find().

    The order you're seeing is this:

    1. Your variable instantiation is synchronous.
    2. Person.find().exec() is asynchronous and doesn't block the main thread.
    3. The main thread isn't blocked, so console.log('Listening on port 3000') runs.
    4. console.log() is synchronous, so var startTime is set.
    5. console.log('wait'); is synchronous and continues after execution.
    6. The while() loop runs. It blocks the main thread.
    7. The event loop resumes, running console.log('0');.
    8. The listen() and console.log('4') functions are both synchronously run.
    9. The Person.find().exec() finally runs and starts the for loop.
    10. The for loop is also blocks. All iterations complete before continuing.
    11. Since the loop has stopped blocking the main thread, console.log('3') is run.
    12. The callbacks of the asynchronous functions within the loop execute.

    As a summary, your program stops at the while() loop because the loop is blocking. If you want to delay execution of code, do so without blocking the main thread by using one of the global timer functions:

    setTimeout(function() {
      console.log('0');
    
      app.listen(3000);
      console.log('4');
    }, 5000);