To my understanding of the event loop, the following code will output 'Sync 2' then 'Sync 4' first (synchronous code), then 'Promise 3' (fetch returns a Promise which would be placed in the microtask queue and will be executed after the synchronous code finishes and data comes back from the API), finally 'Async 1' (setTimeout would be placed in the macrotask/callback queue with the lowest priority).
However, in the lastest version Chrome, I always got 'Async 1' before 'Promise 3' if I set setTimeout() to 0 like below. Is there anything I misunderstand? Is it possible that a not-yet-resolved Promise gets lower priority than something in the macrotask queue here?
setTimeout(() => console.log('Async 1'), 0);
console.log('Sync 2')
fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits').then(() => console.log('Promise 3'))
console.log('Sync 4')
Your fetch
call has to at least go to browser cache and possibly to the network (to revalidate something in cache), so you can't make any assumptions at all about the timing of the call to your fulfillment handler on it other than that it won't be synchronous. The fulfillment handler call might be queued immediately (though I would tend to doubt it) in which case it would run before the next task (the setTimeout
callback), but more likely it will be held up at least briefly. Fundamentally, this is down to the implementation of fetch
in the browser, which is implementation-dependent, not about tasks or microtasks.