I was recently watching a workshop video by Will Sentence on async javascript and I am having trouble understanding whether microtask queue always has priority over macrotask queue.
function display(data) {console.log(data)}
function printHello() {console.log(“Hello”);}
function blockFor300ms() {/* blocks js thread for 300ms with long for loop */}
setTimeout(printHello, 0);
const futureData = fetch('https://twitter.com/will/tweets/1')
futureData.then(display)
blockFor300ms()
console.log(“Me first!”);
In this example, Will explains that printhello is added to the macrotask (callback) queue then the fetch request gets executed and suppose at 201ms of the code exuction, the display callback is added to the microtask queue. Meanwhile the blockFor300ms had blocked the code for 300ms.
At about 301ms Me first! gets console logged, then since the microtask queue has priority over the macrotask queue, the data from the fetch request gets logged and finally the setTimeout's Hello. So the order of the console.logs:
1. console.log("Me first!")
2. console.log(data) // data from fetch request
3. console.log("Hello")
I tried executing similar code example in various environments (Chrome, Firefox, Safari, node), with various blocker functions (with varying durations) and I always get:
1. synchronous code console.log("Me first!")
2. console.log from the setTimeout
3. console.log with data from fetch request .then
I thought maybe the result depends on when the fetch request gets resolved and the data is received but I have also tried blocking the code for more than 10 or 20 seconds and the outcome is always setTimeout first then the fetch. Whats going on here and what's the reason behind this?
Here is the code I tested with:
function display(data) {console.log("Fetched data:", data);}
function printHello() {console.log("Hello")}
function blockForDuration(duration) {
const startTime = Date.now();
while (Date.now() - startTime < duration) {}
}
setTimeout(printHello, 0);
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json())
.then(display)
.catch(error => console.error("Fetch error:", error));
blockForDuration(10000);
console.log("Me first!");
/*
Console log order
1. "Me first!"
2. "Hello"
3. "Fetched data:", data
*/
fetch()Promise chain does not calldisplay()until after the second Promise has resolved (the one forresponse.json()).