I have been playing with Promises, but I am having trouble understanding what is happening with the following code:
const promise = new Promise((resolve, reject) => {
console.log('Promise started - Async code started')
setTimeout(() => {
resolve('Success')
}, 10)
})
setTimeout(() => {
console.log('Promise log inside first setTimeout')
}, 0)
promise.then(res => {
console.log('Promise log after fulfilled')
})
console.log('Promise made - Sync code terminated')
setTimeout(() => {
console.log('Promise log inside second setTimeout')
}, 0)
The output is:
Promise started - Async code started
Promise made - Sync code terminated
Promise log inside first setTimeout
Promise log inside second setTimeout
Promise log after fulfilled
It is as expected.
But let check the output of the below code:
const promise = new Promise((resolve, reject) => {
console.log('Promise started - Async code started')
setTimeout(() => {
resolve('Success')
}, 1)
})
setTimeout(() => {
console.log('Promise log inside first setTimeout')
}, 0)
promise.then(res => {
console.log('Promise log after fulfilled')
})
console.log('Promise made - Sync code terminated')
setTimeout(() => {
console.log('Promise log inside second setTimeout')
}, 0)
Changed the to be resolved promise setTimeout timer value from 10ms to 1ms
The output is:
Promise started - Async code started
Promise made - Sync code terminated
Promise log after fulfilled
Promise log inside first setTimeout
Promise log inside second setTimeout
Any explanation for this?
From Concurrency model and the event loop
setTimeoutdoes not run immediately after its timer expires- Zero delay doesn't actually mean the call back will fire-off after zero milliseconds. Calling
setTimeoutwith a delay of 0 (zero) milliseconds doesn't execute the callback function after the given interval. Basically, thesetTimeoutneeds to wait for all the code for queued messages to complete even though you specified a particular time limit for your setTimeout.
What happen if we set 2 and 1 milliseconds:
const promise = new Promise((resolve, reject) => {
console.log('Promise started - Async code started')
setTimeout(() => {
resolve('Success')
}, 2)
})
console.log('Promise log inside first setTimeout 1')
setTimeout(() => {
console.log('Promise log inside first setTimeout 2')
}, 1)
promise.then(res => {
console.log('Promise log after fulfilled ❌')
})
console.log('Promise log inside second setTimeout 1')
setTimeout(() => {
console.log('Promise log inside second setTimeout 2')
}, 1)
});
The output always will be:
Promise started - Async code started
Promise log inside first setTimeout 1
Promise log inside second setTimeout 1
Promise log inside first setTimeout 2
Promise log inside second setTimeout 2
Promise log after fulfilled ❌
If you want a proper behavior, worth to get rid of Zero delays.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With