【问题标题】:Exiting the forEach before promise is done在承诺完成之前退出 forEach
【发布时间】:2019-06-13 00:09:59
【问题描述】:

我试图在 forEach 循环内调用一个请求,但我的代码在循环完成之前退出了循环。有没有办法确保循环在下一个代码执行之前完成? (我对 Promise 比较陌生)

我的代码遵循这种格式:

let arr = [1, 2, 3, 4, 5, 6];

arr.forEach(num => {
  return request('http://google.com')
    .get('/')
    .then(() => {
      console.log(num);
    });
});
console.log('HERE');

这段代码^记录

HERE
1
2
6
4
5
3

(这些数字是随机排列的,这对我来说并不重要)

但我希望它记录

1
2
3
4
5
6
HERE

我该怎么做?

【问题讨论】:

标签: javascript foreach request-promise


【解决方案1】:

你不能在这种情况下使用forEach

相反,由于您使用的是基于 Promise 的并发,因此您必须将每个请求转换为 Promise (arr.map(num => ...)),然后将所有请求包装在 Promise.all 中,它本身会返回一个在之后解析的 Promise所有包装好的承诺都解决了。

let arr = [1, 2, 3, 4, 5, 6];

Promise.all(
  arr.map(num =>
    request("http://google.com")
      .get("/")
      .then(() => {
        console.log(num);
      })
  )
).then(() => {
  console.log("HERE");
});

【讨论】:

  • 只有在请求按顺序返回时才会产生所需的结果。
  • 并非如此,promise 可以按任何顺序解决,映射发生时它们已经被排序。但如果其中任何一个失败,'Promise.all()` 也会失败。
  • @Guywhotypesfast 确定最终映射结果将按顺序保存值,但 console.logs 将按解析顺序发生。
  • 嗯,你是对的,日志会在每个 promise 被解决时出现。返回数组并在.then() 回调中记录将解决此问题。对吗?
  • 我刚刚注意到:(the numbers are in random order, that's not really what matters to me) 所以可能没关系。
【解决方案2】:

这里是另一个例子。也可以用于

let array = [1, 2, 3, 4, 5, 6];
async function processArray(arr){
  for (const num of array) {
    await request('http://google.com').get('/');
    console.log(num);
  }
  console.log('Done!');
}

processArray(array);

【讨论】:

    猜你喜欢
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 2023-02-17
    • 2019-11-26
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    相关资源
    最近更新 更多