给定以下代码:

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'。

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


当前回答

我推荐使用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。

其他回答

如果映射到promise数组,则可以将它们全部解析为数字数组。看到Promise.all。

这里的问题是,你试图等待一连串的承诺,而不是一个承诺。这并不是你所期望的。

当传递给await的对象不是Promise时,await只是立即返回值,而不是试图解析它。因此,由于这里传递给await的是一个(Promise对象的)数组而不是一个Promise对象,await返回的值就是这个数组,它的类型是Promise<number>[]。

你可能要做的就是给承诺打电话。为了在等待它之前将它转换为单个Promise。

根据Promise.all的MDN文档:

promise .all(iterable)方法返回一个可解析的promise 当iterable实参中的所有promise都已解决时,或者 以拒绝的第一个通过承诺的理由拒绝。

在你的例子中:

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;
}));

这将解决您在这里遇到的特定错误。

根据您想要做的具体内容,您也可以考虑使用Promise。allSettled,承诺。任何,或承诺。竞赛而不是承诺。所有的,尽管在大多数情况下(几乎肯定包括这个)承诺。一切都会是你想要的。

我推荐使用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。

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

您还可以尝试使用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;
  });

解决方案下面正确使用异步等待和数组。地图在一起。并行、异步处理数组中的所有元素,并保持顺序:

Const arr = [1,2,3,4,5,6,7,8]; const randomDelay = () => new Promise(resolve => setTimeout(resolve, Math.random() * 1000)); Const calc = async n => { 等待randomDelay (); 返回n * 2; }; const asyncFunc = async() => { const unresolvedPromises = arr.map(calc); const results = await Promise.all(未解决的promise); document . write(结果); }; document . write(“计算…”); asyncFunc ();

也codepen。

注意,我们只“等待”Promise.all。我们多次调用没有“await”的calc,并立即收集一组未解决的承诺。然后承诺。All等待解析所有这些值,并返回一个包含已解析值的数组。