Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Executing priority of fetch() and setTimeout() in Chrome

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')
like image 763
Johnny Huynh Avatar asked Oct 24 '25 01:10

Johnny Huynh


2 Answers

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.

like image 52
T.J. Crowder Avatar answered Oct 26 '25 15:10

T.J. Crowder


(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)

This is only true if the Promise that is returned resolves immediately - for example, with Promise.resolve. If the Promise returned by fetch resolved immediately, you'd be right, and the Promise 3 would log before the setTimeout's.

But fetch does not resolve immediately - it requires the endpoint to respond first, and that takes some time, so you see the setTimeout log first.

like image 41
CertainPerformance Avatar answered Oct 26 '25 14:10

CertainPerformance