I was reading about micro and macro tasks in the JavaScript stack. I wrote this code:
Promise.resolve().then(function () {
setTimeout(function () {
console.log('from promise one');
}, 0);
}).then(() => {
console.log('from promise two');
});
setTimeout(function () {
console.log('from timeout');
}, 0);
But I realized that from timeout
shows faster than from promise one
in the console...
As I understood, Promise. then()
is a microtask and executes before macro task which from timeout
is a microtask here... but why does execute the timeout
first then Promise. then
?
Important things to know:
setTimeout
with a timeout of 0
will run the function at the beginning of the next event loop.Promise.resolve.then()
are microtasks, and will be run after all of the macrotasks in the current iteration of the event loop have completed.Here's a full explanation:
// The promise.resolve() runs first.
Promise.resolve()
// Because the function calling the setTimeout is within a .then(), it will
// be called at the END of the CURRENT iteration of the event look.
.then(function () {
// The callback inside this setTimeout will be run at the beginning of the
// next event loop; however it will run after the "from timeout" log, because
// the setTimeout is called AFTER the one at the very bottom of the file.
setTimeout(function () {
console.log('from promise one');
}, 0);
})
.then(() => {
// This log will occur first. No other logs will happen on the beginning of the
// first iteration of the event loop, because everything is being called as
// macro tasks except for this one.
console.log('from promise two');
});
// This setTimeout call runs before the other code above runs. That's because
// it is being called as a macro task for the current iteration of the event
// loop. The callback inside of it, however, will be called at the BEGINNING of
// the NEXT event loop.
setTimeout(function () {
console.log('from timeout');
}, 0);
Quick rundown of the order at which things happen with the code above:
FIRST ITERATION OF THE EVENT LOOP:
Promise.resolve()
is calledsetTimeout
at the bottom of the file is called. Queues "from timeout" to be logged at the beginning of the next iteration of the loop.- all macro tasks now finished. moving onto micro tasks -
.then()
callback is called, and the setTimeout within queues up the "from promise one" log to be ran at the beginning of the next iteration of the event loop..then()
callback is called, and "from promise two" is logged.SECOND ITERATION OF THE EVENT LOOP:
Output:
from promise two
from timeout
from promise one
Check out this short video for a succinct explanation of the event loop, microtasks and macrotasks, and asynchronous programming in JavaScript.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With