Recently I've been given a following problem:
console.log("start");
const promise1 = Promise.resolve().then(() => {
console.log("promise1");
const timer2 = setTimeout(() => {
console.log("timer2");
}, 0);
});
const timer1 = setTimeout(() => {
console.log("timer1");
const promise2 = Promise.resolve().then(() => {
console.log("promise2");
});
}, 0);
console.log("end");
My initial answer was start, end, promise1, timer2, promise2, timer1 (wrong one).
I understand that synchronous code executes first then microtasks and then macrotasks. I also understand that microtask may appear between two macrotasks. I'm slightly confused and not fully aware why timer2 wasn't queued by macrotask when we were executing promise1 in a callstack. I also understand that JS engine read and queued timer1 while we were processing promise1, but can't fully understand the reason for it.
To me it seems like globally declared values are read first.
Below is the principle that solves the order of a problem:
- First, all micro tasks are performed. (I assume this means all global microtasks first.)
- One macro task is performed.
- All (re-added) micro-tasks are re-tasks.
- The following macro problem is executed.
- Cycle repeats / Cycle ends.
By this principle, it seems that global values are considered first. I understand the logic behind the answer, but can't find any answers on whether "global values are considered first statement" is true. I'm not sure why timer2 wasn't queued when we processed promise1. I somewhat believe it was queued but timer1 was processed faster than timer2 since it is declared globally . Was timer1 read first and queued before timer2 because it is in global scope? What is the reason for it? I somewhat understand it but not entirely sure.