Use async await with Array.map

不问归期 提交于 2019-11-26 14:55:25
Ajedi32

The problem here is that you are trying to await an array of promises rather than a promise. This doesn't do what you expect.

When the object passed to await is not a Promise, await simply returns the value as-is immediately instead of trying to resolve it. So since you passed await an array (of Promise objects) here instead of a Promise, the value returned by await is simply that array, which is of type Promise<number>[].

What you need to do here is call Promise.all on the array returned by map in order to convert it to a single Promise before awaiting it.

According to the MDN docs for Promise.all:

The Promise.all(iterable) method returns a promise that resolves when all of the promises in the iterable argument have resolved, or rejects with the reason of the first passed promise that rejects.

So in your case:

var arr = [1, 2, 3, 4, 5];

var results: number[] = await Promise.all(arr.map(async (item): Promise<number> => {
    await callAsynchronousOperation(item);
    return item + 1;
}));

This will resolve the specific error you are encountering here.

Gabriel Cheung

There's another solution for it if you are not using native Promises but Bluebird.

You could also try using Promise.map(), mixing the array.map and Promise.all

In you case:

  var arr = [1,2,3,4,5];

  var results: number[] = await Promise.map(arr, async (item): Promise<number> => {
    await callAsynchronousOperation(item);
    return item + 1;
  });

If you map to an array of Promises, you can then resolve them all to an array of numbers. See Promise.all.

Beckster

I'd recommend using Promise.all as mentioned above, but if you really feel like avoiding that approach, you can do a for or any other loop:

const arr = [1,2,3,4,5];
let resultingArr = [];
for (let i in arr){
  await callAsynchronousOperation(i);
  resultingArr.push(i + 1)
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!