我有一个正在映射的数组,在映射函数内部,我正在调用一个异步函数,该函数使用request-promise
执行返回promise的异步请求。
我希望数组的第一个项被映射,执行请求,然后第二个项重复相同的过程。但这种情况并非如此。
这是我的职责;
const fn = async() => {
const array = [0, 1, 2];
console.log('begin');
await Promise.all(array.map(item => anAsyncFunction(item)));
console.log('finished');
return;
}
CCD_ 2如下;
const anAsyncFunction = async item => {
console.log(`looping ${item}`);
const awaitingRequest = await functionWithPromise(item);
console.log(`finished looping ${item}`);
return awaitingRequest;
}
以及functionWithPromise
,其中请求是
const functionWithPromise = async (item) => {
console.log(`performing request for ${item}`);
return Promise.resolve(await request(`https://www.google.com/`).then(() => {
console.log(`finished performing request for ${item}`);
return item;
}));
}
从控制台日志我得到;
begin
looping 0
performing request for 0
looping 1
performing request for 1
looping 2
performing request for 2
finished performing request for 0
finished looping 0
finished performing request for 1
finished looping 1
finished performing request for 2
finished looping 2
finished
然而,我想要的是
begin
looping 0
performing request for 0
finished performing request for 0
finished looping 0
looping 1
performing request for 1
finished performing request for 1
finished looping 1
looping 2
performing request for 2
finished performing request for 2
finished looping 2
finished
我通常可以接受这种模式,但我似乎从请求调用中得到了一些无效的正文,因为我可能一次做了太多。
有没有更好的方法来实现我正在尝试的
.map()
不是异步的,也不是承诺感知的。它只是尽职尽责地获取您从其回调中返回的值,并将其填充到结果数组中。即使在你的情况下这是一个承诺,它仍然会继续,而不是等待那个承诺。在这方面,您无法更改.map()
行为。这就是它的工作方式。
相反,在循环中使用for
循环,然后使用await
异步函数,这将挂起循环。
您的结构:
await Promise.all(array.map(item => anAsyncFunction(item)));
正在并行运行所有anAsyncFunction()
调用,然后等待所有调用完成。
要按顺序运行它们,请使用for
循环和await
单个函数调用:
const fn = async() => {
const array = [0, 1, 2];
console.log('begin');
for (let item of array) {
await anAsyncFunction(item);
}
console.log('finished');
return;
}
重要的是要知道,没有一个数组迭代方法是异步感知的。这包括.map()
、.filter()
、.forEach()
等。因此,如果您想等待循环中的某些内容以便对异步操作进行排序,那么请使用一个常规的for
循环,该循环可感知async
并将暂停循环。
您可以尝试替换此行:
await Promise.all(array.map(item => anAsyncFunction(item)));
带有:
await Promise.all(array.map(async(item) => await anAsyncFunction(item)));
与for循环备选方案相比,nodejs的工作方式应该更多,在这种情况下,只有forEach被禁止。