John Doe
John Doe

Reputation: 189

Why does the following code always print the timeout before the immediate?

Why does the following always appear:

0

...

999

Inside the timeout

Inside the immediate

Shouldn't the setImmediate have precedence in the callback queue?

setImmediate(()=>{
    console.log('Inside the immediate');
});

setTimeout(()=> {
    console.log('Inside the timeout');
}, 1);

for (let i = 0; i < 1000; i++) {
    console.log(i);
}

Upvotes: 2

Views: 120

Answers (1)

JoshG
JoshG

Reputation: 6735

There are a few issues on GitHub that reference this behavior. A comment on one of these issues does a pretty good job at explaining why it happens:

What happens with the code you mentioned is that the timer and the immediate are added, and then the libuv event loop starts. When it starts, the libuv event loop first check for timers, and if the time between when a timer was added and when the event loop starts is greater than the timer's timeout value, then that timer will fire before any immediate.

So basically, if you haven't yet entered the event loop, the callback in your setTimeout is going to get executed on the first tick. Otherwise, the setImmediate will get executed first.

As a demonstration, if you wrap a setTimeout and setImmediate in another setTimeout, the setImmediate gets executed first:

setTimeout(function() {
    setTimeout(function() {
        console.log('setTimeout executed!')
    }, 0);
    setImmediate(function() {
        console.log('setImmediate executed!')
    });
}, 20);

Upvotes: 1

Related Questions