给定以下代码:

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

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

这会产生以下错误:

TS2322:类型“Promise<number>[]”不能分配给类型“number[]”。 类型'Promise<number>不能分配给类型'number'。

我该怎么解决呢?我如何使异步等待和数组。地图一起工作?


当前回答

使用modern-async's map()的解决方案:

import { map } from 'modern-async'

...
const result = await map(myArray, async (v) => {
    ...
})

使用该库的优点是可以使用mapLimit()或mapSeries()控制并发性。

其他回答

如果你使用的不是本地承诺而是蓝鸟,还有另一个解决方案。

您还可以尝试使用Promise.map(),混合数组。地图和承诺。所有

对你来说:

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

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

使用modern-async's map()的解决方案:

import { map } from 'modern-async'

...
const result = await map(myArray, async (v) => {
    ...
})

使用该库的优点是可以使用mapLimit()或mapSeries()控制并发性。

这是最简单的方法。

await Promise.all(
    arr.map(async (element) => {
        ....
    })
)

我推荐使用Promise。如上所述,但如果你真的想避免这种方法,你可以做一个for循环或任何其他循环:

const arr = [1,2,3,4,5];
let resultingArr = [];
for (let i in arr){
  await callAsynchronousOperation(i);
  resultingArr.push(i + 1)
}

供参考:如果你想迭代数组的项,而不是索引(@ralfoide的评论),在arr语句中使用of而不是in inside let i。

你可以使用:

for await (let resolvedPromise of arrayOfPromises) {
  console.log(resolvedPromise)
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of

如果你想使用Promise.all(),你可以使用promise . allsettle () 所以你可以更好地控制被拒绝的承诺。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled