最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Returning array populated in loop by async function - Stack Overflow

programmeradmin1浏览0评论

I think this is a fairly simple question, but I primarily program in ruby and ma having trouble wrapping my head around asynchronous functions in javascript. Specifically, I have a method that is supposed to populate an array with results fetched asynchronously from an API. I am able to get the results fine, but I can't seem to return the array after it has been populated. Rather, the return statement executes before the promise is resolved, so an empty array is returned. Simplified code example below:

async function getAnimalSounds(animals){
   var sounds = []
   for (const a of animals){
     asynchronously_fetch_sound(a).then((result) => {
       sounds.push(result)
     })
   }
   
   return sounds // sounds returns as an empty array
}

Thank you in advance!

I think this is a fairly simple question, but I primarily program in ruby and ma having trouble wrapping my head around asynchronous functions in javascript. Specifically, I have a method that is supposed to populate an array with results fetched asynchronously from an API. I am able to get the results fine, but I can't seem to return the array after it has been populated. Rather, the return statement executes before the promise is resolved, so an empty array is returned. Simplified code example below:

async function getAnimalSounds(animals){
   var sounds = []
   for (const a of animals){
     asynchronously_fetch_sound(a).then((result) => {
       sounds.push(result)
     })
   }
   
   return sounds // sounds returns as an empty array
}

Thank you in advance!

Share Improve this question asked Nov 29, 2020 at 15:08 MattMatt 5185 silver badges15 bronze badges 1
  • 1 See the "multiple asynchronous operations" part of my answer here. – T.J. Crowder Commented Nov 29, 2020 at 15:12
Add a ment  | 

3 Answers 3

Reset to default 8

The problem here is that you are using a plain for loop to traverse the animals array. Loops in NodeJS won't wait for the promise of the current iteration to resolve before moving onto the next, so the loop will finish before you have resolved your promises.

The best thing to do is to construct an array of promises you want to resolve, and then call Promise.all on that array.

async function getAnimalSounds(animals){
    const promises = animals.map(a => asynchronously_fetch_sound(a))
    const sounds = await Promise.all(promises)

    return sounds
}

Or if you're happy to use the Bluebird library (docs here), you can do this:

const Bluebird = require('bluebird') // import Bluebird library

async function getAnimalSounds(animals){
    const sounds = await Bluebird.map(animals, (a) => asynchronously_fetch_sound(a))

    return sounds
}

Remember that since you have written an async function, you will need to wait for it to resolve before doing anything with its output; either by awaiting it or by calling .then(...).

You should add await for the asynchronous method call.

async function getAnimalSounds(animals){
   var sounds = []
   for (const a of animals){
     const result = await asynchronously_fetch_sound(a);
     sounds.push(result)
   }
   
   return sounds // sounds returns as an empty array
}

However, the best practice is to use Promise.all()

async function getAnimalSounds(animals){
   var sounds = []
   const promises = []
   for (const a of animals){
     promises.push(asynchronously_fetch_sound(a));
   }
   sounds = await Promise.all(promises);

   return sounds;
}

You can use Promise.all() to achieve that:

function getAnimalSounds(animals){
   return Promise.all(animals.map(a => asynchronously_fetch_sound(a)));
}
发布评论

评论列表(0)

  1. 暂无评论