Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

node.js: while loop callback not working as expected

Knowing that while Node.js is working asynchronously, writing something like this:

function sleep() {
    var stop = new Date().getTime();
    while(new Date().getTime < stop + 15000) {
        ;
    }
}

sleep();
console.log("done");

...would call the sleep(), block the server for the duration of the while loop (15secs) and just THEN print "done" to the console. As far as I understand, this is because Node.js is giving JavaScript only access to the main thread, and therefore this kidn of thing would halt further execution.

So I understand the solution to this is to use callbacks:

function sleep(callback) {
    var stop = new Date().getTime();
    while(new Date().getTime() < stop + 15000) {
        ;
    }
    callback();
}

sleep(function() {
    console.log("done sleeping");
});

console.log("DONE");

So I thought this would print 'DONE' and after 15 secs. 'done sleeping', since the sleep() function gets called and is handed a pointer to a callback function. While this function is working (the while loop), the last line would be executed (print 'done'). After 15 seconds, when the sleep() function finishes, it calls the given callback function, which then prints 'done sleeping'.

Apparently I understood something wrong here, because both of the above ways block. Can anybody clarify please?

Thanks in advance, Slagjoeyoco

like image 617
slagjoeyoco Avatar asked Oct 13 '12 00:10

slagjoeyoco


People also ask

Are while loops blocking?

while , while and foreach . However, all of these structures block the imp's processor. If the code needs to run through the loop only a handful of times, that's not a problem.

What is faster callback or promise in Nodejs?

So from my findings i assure you ES6 promises are faster and recommended than old callbacks.

Is while loop blocking in Javascript?

Loops can execute a block of code as long as a specified condition is true.

How many callbacks can respond to any event in Node js?

It will return the max listeners value set by setMaxListeners() or default value 10. By default, a maximum of 10 listeners can be registered for any single event.


2 Answers

Javascript and node.js are single threaded, which means a simple while blocks; no requests/events can be processed until the while block is done. Callbacks don't magically solve this problem, they just help pass custom code to a function. Instead, iterate using process.nextTick, which will give you esentially the same results but leaves space for requests and events to be processed as well, ie, it doesn't block:

function doSleep(callback) {
    var stop = new Date().getTime();

    process.nextTick(function() {
        if(new Date().getTime() < stop + 15000) {
            //Done, run callback
            if(typeof callback == "function") {
                callback();
            }
        } else {
            //Not done, keep looping
            process.nextTick(arguments.callee);
        }
    });
}

doSleep(function() {
    console.log("done sleeping");
    console.log("DONE");
});
like image 94
Mahn Avatar answered Sep 22 '22 19:09

Mahn


You are calling sleep right away, and the new sleep function blocks. It keeps iterating until the condition is met. You should use setTimeout() to avoid blocking:

setTimeout(function () {
    console.log('done sleeping');
}, 15000);
like image 9
Abdullah Jibaly Avatar answered Sep 21 '22 19:09

Abdullah Jibaly