异步等待映射在映射下一项之前不等待异步函数在映射函数内部完成

mcc*_*osa 0 javascript promise express async-await request-promise

我有一个要映射的数组,在我正在调用的映射函数内部调用一个异步函数,该函数执行异步请求,使用request-promise.

我期望映射数组的第一项,执行请求,然后第二项重复相同的过程。但在这种情况下,情况并非如此。

这是我的职责;

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

anAsyncFunction 如下;

const anAsyncFunction = async item => {
  console.log(`looping ${item}`);
  const awaitingRequest = await functionWithPromise(item);
  console.log(`finished looping ${item}`);
  return awaitingRequest;
}
Run Code Online (Sandbox Code Playgroud)

以及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;
  }));
}
Run Code Online (Sandbox Code Playgroud)

从我得到的控制台日志中;

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
Run Code Online (Sandbox Code Playgroud)

然而,我想要的是

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
Run Code Online (Sandbox Code Playgroud)

我通常对这种模式没问题,但我似乎从请求调用中得到了一些无效的主体,因为我可能一次做太多。

有没有更好的方法来实现我的目标

jfr*_*d00 8

.map()不知道异步或承诺。它只是尽职尽责地获取您从其回调返回的值并将其填充到结果数组中。即使在你的情况下这是一个承诺,它仍然会继续前进,而不是等待那个承诺。并且,在这方面您无能为力来改变.map()行为。这就是它的工作方式。

相反,使用for循环,然后await在循环内使用异步函数,这将挂起循环。


你的结构:

await Promise.all(array.map(item => anAsyncFunction(item)));
Run Code Online (Sandbox Code Playgroud)

正在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;
}
Run Code Online (Sandbox Code Playgroud)

要知道没有一个数组迭代方法是异步感知的,这一点很重要。这包括.map(), .filter(), .forEach(), 等等...因此,如果您想在循环中等待某些内容以对异步操作进行排序,请使用forasync感知并暂停循环的常规循环。