1

I'm trying to understand a little bit of NodeJS. The logic below is supposedly, when readdir is done, it would set the flag so the while loop would stop. Apparently it doesn't work this way. To my understand it is more like an event thing, but what I'm trying to do is not important, I'm more interested in how it works and why. Is it because while loops are blocking(?)?

var dirm = require('./dirm.js');
var flag = false;
dirm(process.argv[2], process.argv[3], function(err, data) {
    flag = true;
    if (err)
        console.log(err);
    data.forEach(function(file) {
        console.log(file);
    })
})
while (flag == false) {
    console.log('Hey');
}

2 Answers 2

1

It works this way:

  1. The drim function registers an anonymous callback (function(err,data)) to be executed later (presumably when it is complete). It also schedules its own asynchronous operation (tell the interpreter that it needs to drim something).

  2. You run the while loop

  3. The interpreter is waiting for the end of script to see if has anything else to do (drim something and when that is done at a much later time run the scheduled callback).

  4. ... there is no number 4 because the while loop never completes therefore the end of script is never reached therefore the interpreter doesn't get the chance to run anything on its own.

In most other languages like C or Python the asynchronous library requires you to execute your own function to run the eventloop. Something like this:

async_function(callback);
eventloop.run(); // this allows the async function to work

In those languages it's obvious why inserting a while loop before running the eventloop means the eventloop never runs:

async_function(callback);
while (1) { /* do nothing */ }
eventloop.run(); // never gets run

In javascript, the eventloop is not a library, it's built-in. Therefore the eventloop.run is executed silently at the end of the script:

async_function(callback);

// eventloop runs here

Additional Answer

To get the semantics of your while loop (waiting for a flag to be set) working asynchronously you can always replace it with a setInterval or setTimeout loop:

setInterval(function(){
    if (flag == false) {
        console.log('Hey');
    }
},10); // check 100 times per second

To stop the setInterval just call clearInterval:

var loop = setInterval(function(){
    if (flag == false) {
        console.log('Hey');
    }
    else {
        clearInterval(loop); // stop the loop
    }
},10);
Sign up to request clarification or add additional context in comments.

4 Comments

I was thinking the callback would be interrupt like. Thanks for the detailed explanation.
If you're comfortable with C programming, what actually happens in the eventloop is a loop around select() or epoll() which puts the process to sleep and the OS will wake it up for I/O events or timeouts.
Thanks. This is what I'm looking for function r() { if (!flag) { console.log("Hey"); setImmediate(r); } }
You can always replace a synchronous while loop with an asynchronous setInterval loop to do what you want.
1

Javascript in node.js is executed in a single thread in an event loop, so there is no way for the asynchronous callback to be executed until the while loop is finished.

1 Comment

Too bad I can only pick one answer. Cheers.

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.