(async function iife () {
const numbers = [1, 2, 3, 4]
let count = 0
async function returnNumberAsync (number) {
return new Promise(resolve => {
setTimeout(() => resolve(number), 0)
})
}
await Promise.all(numbers.map(async number => {
count += await returnNumberAsync(number)
}))
console.log(count)
})()
This snippet logs 4 to the console, which is completely beyond me. As soon as I assign the promised value inside map to its own local variable …
const result = await returnNumberAsync(number)
count += result;
… it logs 10 like I'd expect. What's happening when I count += await …??
When you do count += await <expression>, the initial value of count to be added to the resolve value is saved before the await part is resolved. So
count += await returnNumberAsync(number)
is like
count = count + await returnNumberAsync(number)
as you can see:
(async function iife () {
const numbers = [1, 2, 3, 4]
let count = 0
async function returnNumberAsync (number) {
return new Promise(resolve => {
setTimeout(() => resolve(number), 0)
})
}
await Promise.all(numbers.map(async number => {
count = count + await returnNumberAsync(number)
}))
console.log(count)
})()
In each of the 4 closures, count is seen to be 0 before the awaits resolve, so only in the final await microtask, where it resolves to
count += await returnNumberAsync(4)
// or
count = 0 + await returnNumberAsync(4)
// or
count = 4
does 4 get assigned to count. The fact that other numbers were assigned to count earlier is ignored. They did happen, but the assignment of the final iteration is all you see with the current code.
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