setTimeout(fn, 0)
0 ms is a minimum delay, not 'run now'. The callback is still queued as a task, so it waits for the current code and all microtasks first — it never runs immediately.
Logging 'A' (sync), 'B' (promise), 'C' (setTimeout 0) prints A, B, C — even if the timer was set first.
log('A')
setTimeout(() => log('C'), 0)
Promise.resolve().then(() => log('B'))
out
Async
Bpromise
Ctimeout 0