If you add another console log in the reducer you can see what is happening.
(async () =>
console.log(
await [("apple", "banana", "orange")].reduce(async (o, fruit) => {
console.dir({o, fruit})
const random_number = await new Promise((resolve) => setTimeout(() => resolve(Math.random()), 200));
return { ...o, [fruit]: random_number };
}, {})
))();
output:
{ o: {}, fruit: 'orange' }
{ orange: 0.39647395383957074 }
This is because you have wrapped your array item in parentheses [("apple", "banana", "orange")]
so there is only one item to reduce.
After fixing this the output is
{ o: {}, fruit: 'apple' }
{ o: Promise { <pending> }, fruit: 'banana' }
{ o: Promise { <pending> }, fruit: 'orange' }
{ orange: 0.8347447113637538 }
Now you can see that the promises are not properly awaited. @Mulan already gave the answer for this so I won't repeat it.
I will suggest using map
instead of reduce
for this. This will stop the promises from blocking one another, in your reduce code the reducer must wait for one promise to complete before moving the the next. If you gather all the promises together and await them using Promise.all
you can avoid this.
(async () => {
//map the array to an array of promises
const promises = ["apple", "banana", "orange"].map(async (fruit) => {
const random_number = await new Promise((resolve) => setTimeout(() => resolve(Math.random()), 200));
return { [fruit]: random_number };
});
//wait for all promises to resolve
const results = await Promise.all(promises);
//merge the result objects together
const result = Object.assign(...results);
console.log(result)
})();