I'm getting confused on how the following testcode would be put into the JS event loop.
var p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(1)
}, 100)
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(2)
}, 0)
});
p1.then((value)=>{console.log(value)})
p2.then((value)=>{console.log(value)})
From my understanding, wouldn't the setTimeout functions be synchronously called and then right after the two .then events be added into the microtask queue? But wouldn't this mean that at the end of the current iteration the two microtasks are ran before the resolve functions are even ran? Or is it that when resolve functions are called, all microtasks related to that promise are called at the end of the current iteration?
I think it would be best if somebody could just explain to me step-by-step on how the code is added into the event loop and then ran.
wouldn't the setTimeout functions be synchronously called
Yes, the setTimeout
will be invoked synchronously.
and then right after the two .then events be added into the microtask queue?
No. Calling setTimeout
schedules a task in the task queue to execute the callback, passed to the setTimeout
call, when the timer expires. Even if you pass zero as the delay, the callback will be invoked asynchronously.
But wouldn't this mean that at the end of the current iteration the two microtasks are ran before the resolve functions are even ran?
Both promises will be resolved asynchronously. After the synchronous execution of the code ends, even loop can start processing the scheduled callbacks as a result of two setTimeout
calls in your code.
It is only when a promise is resolved and their is a fulfilment handler registered for that promise, a job is queued in the micro-task queue to execute the fulfilment handler.
Following steps describe your code execution:
Both promises are created as a result of Promise
constructor calls. The function passed to the Promise
constructor is called synchronously as part of promise creation process. As a result, two setTimeout
callbacks are scheduled to be executed once their respective timer expires.
After both promises are created one after the other, then
methods are called on promises p1
and p2
respectively. This registers fulfilment handlers for both promises.
At this point, the synchronous execution of the code has ended. Now the event loop will process any callbacks scheduled in the task queue. Both setTimeout
callbacks will be put into the task queue once their respective timer expires.
Once both setTimeout
callbacks are executed, both promises are resolved one after the other. As soon as any promise is resolved, to execute its fulfilment handlers, a job is enqueued in the micro-task queue. In total there will be two jobs enqueued in the micro-task queue one after the other to execute fulfilment handlers of both promises.