Q: I am confused between JavaScript macro and micro tasks priority 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?

A: Important things to know:

*

*setTimeout with a timeout of 0 will run the function at the beginning of the next event loop.

*The callbacks in 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 called

*The setTimeout 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 -


*First .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.

*Second .then() callback is called, and "from promise two" is logged.

SECOND ITERATION OF THE EVENT LOOP:

*

*"from timeout" is logged first, because it was the first macro task to be queued during the previous event loop iteration.

*"from promise one" is logged.

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.
