Async/Await not working as expected with Promise.all and a .map function

Zach picture Zach · Apr 3, 2017 · Viewed 7.9k times · Source

I have a slew of async functions I'm using and I'm having a weird issue.

My code, working, looks like:

async mainAsyncFunc (metadata) {
  let files = metadata.map(data => this.anotherAsyncFunc(data.url));
  return Promise.all(files);
}

anotherAsyncFunc function looks like:

  async anotherAsyncFunc (url) {
    return await axios({
      url,
    }).then(res => res.data)
      .catch(err => {
      throw err;
    });
  }

My issue comes when I try to append more data to what the first function (mainAsyncFunc) returns. My thoughts are to do that in the map, naturally, and when all is said and done, modified it looks like:

async mainAsyncFunc (metadata) {
    files = metadata.map(data => {
        return new Promise((resolve) => {
          let file = this.anotherAsyncFunc(data.download_url);
          let fileName = data.name;
          resolve({
            file,
            fileName
          });
        });
      });
    return Promise.all(files);
}

If it's not clear, I'm getting the file itself like normal, and appending a fileName to it, then resolving that object back.

For some reason, this is returning a pending Promise, whereas I would expect it to wait for them to be fulfilled and then returned as a complete file and name in an object. Any help understanding what I'm doing wrong would be greatly appreciated.

Answer

JLRishe picture JLRishe · Apr 3, 2017

It looks like you've solved your issue, just as a bit of a pointer, you can further simplify your code as follows:

async anotherAsyncFunc (url) {
    return (await axios({ url })).data;
}

async mainAsyncFunc (metadata) {
    let files = metadata.map(async data => ({
        file: await this.anotherAsyncFunc(data.download_url),
        fileName: data.name
    }));

    return Promise.all(files);
}