Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

372
Visualizações
Why reduce with async function returns only the last object

I'm trying to set random number to all fruits in array and return an object containing all the fruits with async function in reducer, but only the last element of array is returned

(async () =>
  console.log(
    await [("apple", "banana", "orange")].reduce(async (o, fruit) => {
      const random_number = await new Promise((resolve) => setTimeout(() => resolve(Math.random()), 200));
      return { ...o, [fruit]: random_number };
    }, {})
  ))();

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

You're very close. The main issue is that you wrote the array as [(...)] instead of [...]. In your code, the array only contains one value, if you remove the () you will have three values. See comma operator for details.

The other thing you have to consider is that an async function always returns a promise, so you must await o as well -

(async () =>
  console.log(
    await ["apple", "banana", "orange"].reduce(async (o, fruit) => {
      const rand = new Promise((resolve) => setTimeout(() => resolve(Math.random()), 200))
      return { ...await o, [fruit]: await rand }
    }, {})
  ))();

{
  "apple": 0.8731611352383968,
  "banana": 0.163521266739585,
  "orange": 0.8419246752641664
}

Note reduce as used above will resolve the promises in series (sequentially). Other comments suggesting map->Promise.all will resolve the promises in parallel (simultaneously)

about 4 years ago · Juan Pablo Isaza Relatório

0

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)
  })();
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda