繁体   English   中英

异步等待 map 不等待异步 function 在 map ZC1C425268E68385D14ZA7 映射之前完成

[英]Async Await map not awaiting async function to complete inside map function before mapping next item

I have an array that I am mapping, inside the map function I am calling an asynchronous function, that is performing an asynchronous request returning a promise using request-promise .

我期待数组的第一项被映射,执行请求,然后第二项重复相同的过程。 但这不是在这种情况下发生的事情。

这是我的 function;

const fn = async() => {
  const array = [0, 1, 2];
  console.log('begin');
  await Promise.all(array.map(item => anAsyncFunction(item)));
  console.log('finished');
  return;
}

anAsyncFunction如下;

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()等......所以,如果你想在循环中等待一些东西以对你的异步操作进行排序,那么使用一个async感知的常规for循环并将暂停循环。

您可以尝试替换此行:

await Promise.all(array.map(item => anAsyncFunction(item)));

和:

await Promise.all(array.map(async(item) => await anAsyncFunction(item)));

应该比 for 循环替代更多的 nodejs 方式,在这种情况下只有 forEach 是禁止的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM