2

As my understand, if both macrotask queue and microtask queue have some items ready to run, microtask get higher priority.

I'm testing my code by waiting for both queues filled up to see if this is true, but it's not the case with setTimeout 0ms. Timeout 0ms always runs first.

If I add javascript Promise.resolve('Promise').then(displayData) , this will run first even before setTimeout 0ms

Anyone can explain why is that?

// after 3000ms:
// task queue:printFoo(0ms), printHi(1ms), PrintHello(2ms)
// microtask queue: displayData (about 50ms)

function printHello() {
  console.log("hello");
}

function printHi() {
  console.log("hi");
}

function printFoo() {
  console.log("foo");
}

function displayData(data) {
  console.log("data", data);
}

function sleep(miliseconds) {
  var currentTime = new Date().getTime();
  while (currentTime + miliseconds >= new Date().getTime()) {}
}

setTimeout(printHi, 1);
setTimeout(printHello, 2);
setTimeout(printFoo, 0);
fetch("https://jsonplaceholder.typicode.com/todos/1").then(displayData); // ~~ 50ms
// Promise.resolve('Promise').then(displayData);
sleep(3000);

Output:

foo
data from fetch
hi
hello
ggorlen
  • 44,755
  • 7
  • 76
  • 106
Loc To
  • 21
  • 2

1 Answers1

0

The Promise returned by fetch() will only get resolved in another task, which will fire on the Networking task queue, which has lower or same priority than the Timer task queue. (See this prior answer of mine for links.)

Note: microtasks don't participate in the task prioritization system and are always executed as soon as they can, which in general is as soon as the JS call stack is empty.

Kaiido
  • 123,334
  • 13
  • 219
  • 285