在承诺完成之前退出 forEach
Posted
技术标签:
【中文标题】在承诺完成之前退出 forEach【英文标题】:Exiting the forEach before promise is done 【发布时间】: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
我该怎么做?
【问题讨论】:
Callback after all asynchronous forEach callbacks are completed的可能重复 代码在完成之前不会退出循环,这就是异步代码的工作方式。你触发了一堆异步调用,然后它就停止了。循环结束后调用结束。 【参考方案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);
【讨论】:
以上是关于在承诺完成之前退出 forEach的主要内容,如果未能解决你的问题,请参考以下文章