Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对Array.map使用异步等待_Javascript_Typescript_Promise_Async Await_Ecmascript 2017 - Fatal编程技术网

Javascript 对Array.map使用异步等待

Javascript 对Array.map使用异步等待,javascript,typescript,promise,async-await,ecmascript-2017,Javascript,Typescript,Promise,Async Await,Ecmascript 2017,给定以下代码: var arr = [1,2,3,4,5]; var results: number[] = await arr.map(async (item): Promise<number> => { await callAsynchronousOperation(item); return item + 1; }); var-arr=[1,2,3,4,5]; var结果:number[]=await arr.map(异步(项目

给定以下代码:

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

var results: number[] = await arr.map(async (item): Promise<number> => {
        await callAsynchronousOperation(item);
        return item + 1;
    });
var-arr=[1,2,3,4,5];
var结果:number[]=await arr.map(异步(项目):Promise=>{
等待调用异步操作(项);
退货项目+1;
});
这将产生以下错误:

TS2322:类型“承诺[]”不可分配给类型“编号[]”。 类型“承诺”不可分配给类型“编号”


我怎样才能修好它?如何使
async wait
Array.map
一起工作?

如果映射到承诺数组,则可以将它们全部解析为数字数组。请参阅。

这里的问题是,您试图等待的是一系列承诺,而不是承诺。这不是你所期望的

当传递给
await
的对象不是承诺时,
await
只是立即返回值,而不是尝试解析它。因此,由于您在此处传递了
await
一个数组(Promise对象的数组),而不是Promise,因此await返回的值只是该数组,它的类型为
Promise[]

这里需要做的是调用
Promise.map
返回的数组中的所有
,以便在
等待它之前将其转换为单个Promise

根据报告:

Promise.all(iterable)
方法返回解析的Promise 当iterable争论中的所有承诺都已解决时,或 以第一次通过的拒绝承诺为理由拒绝

因此,在你的情况下:

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;
}));
var-arr=[1,2,3,4,5];
var结果:number[]=等待承诺.all(arr.map)(异步(项目):承诺=>{
等待调用异步操作(项);
退货项目+1;
}));

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

我建议使用上面提到的Promise.all,但如果您确实想避免这种方法,可以执行for或任何其他循环:

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

FYI:如果你想迭代数组中的项目,而不是索引(@ralfoide的评论),请使用
of
而不是
in
in
语句中的

如果你不是使用本机承诺,而是使用蓝鸟,那么还有另一种解决方案

您还可以尝试使用,混合使用array.map和Promise.all

就你而言:

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

  var results: number[] = await Promise.map(arr, async (item): Promise<number> => {
    await callAsynchronousOperation(item);
    return item + 1;
  });
var-arr=[1,2,3,4,5];
var结果:number[]=wait Promise.map(arr,async(项目):Promise=>{
等待调用异步操作(项);
退货项目+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 => {
  await randomDelay();
  return n * 2;
};

const asyncFunc = async () => {
  const unresolvedPromises = arr.map(n => calc(n));
  const results = await Promise.all(unresolvedPromises);
};

asyncFunc();
还有


请注意,我们只“等待”承诺。我们多次在没有“等待”的情况下调用calc,并立即收集一系列未解决的承诺。然后Promise.all等待所有实体的解析,并按顺序返回一个包含解析值的数组。

我的任务是从repo中查找所有实体,添加新的属性url并返回控制器层。我就是这样做到的(感谢Ajedi32的回复):

async findAll():Promise{
const images=wait this.imageRepository.find();//这是一个类型为Image(DB entity)的数组
const host=this.request.get('host');
const mappedImages=wait Promise.all(images.map(image=>({…image,url:`http://${host}/images/${image.id}`}));//这是对象类型的数组
返回plainToClass(ImageResponse,mappedImages);//结果是ImageResponse类型的数组
}
注意:图像(实体)没有属性url,但ImageResponse-有

您可以使用:

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

如果您希望使用
Promise.all()
替代,您可以使用
Promise.allsolited()
所以你可以更好地控制被拒绝的承诺

使用以下方法的解决方案:


使用该库的优点是,您可以使用或来控制并发性。

为什么要尝试将同步操作转换为异步操作
arr.map()
是同步的,不返回承诺。您不能向函数发送异步操作,如
map
,它需要一个同步操作,并期望它工作。@jfriend00我在内部函数中有许多等待语句。它实际上是一个很长的函数,我只是简化了它以使其可读。我现在添加了一个wait调用,以更清楚地说明为什么它应该是异步的。您需要等待返回承诺的内容,而不是返回数组的内容。需要了解的一件有用的事情是,每次将函数标记为
async
,您都在使该函数返回承诺。当然,异步映射会返回一个承诺数组:)冒号是什么意思?@DanielPendergast它用于TypeScript中的类型注释。调用
callAsynchronousOperation(item)有什么区别
在异步映射函数中使用和不使用
wait
?@nerdizle这听起来像是另一个问题的好候选。基本上,使用
await
函数将等待异步操作完成(或失败),然后再继续,否则它将立即继续,而不等待响应。@Ajedi32 thx。但是如果异步映射中没有wait,就不可能再等待函数的重新结果了?它是不同的-它不会并行运行所有操作,而是按顺序执行它们。@AndreyTserkus
Promise.mapSeries
Promise。每个
都是顺序的,
Promise.map
一次启动所有操作。@AndreyTserkus您可以通过提供
concurrency
选项并行运行所有或部分操作。值得一提的是,它不是一个普通的JS。Promise.all对于数组的每个元素都是异步的。这将是一个同步,它必须等待完成一个元素才能开始下一个元素。对于尝试这种方法的人,请注意。。
for await (let resolvedPromise of arrayOfPromises) {
  console.log(resolvedPromise)
}
import { map } from 'modern-async'

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