簡體   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