forEach 中使用 await
forEach 不支持 await,使用 for...of 或 for 循环代替
问题
在 forEach 中使用 await 无法按预期顺序执行异步操作。
async function test() {
let arr = [3, 2, 1];
arr.forEach(async (item) => {
const res = await fetch(item);
console.log(res);
});
console.log("end");
}
function fetch(x) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(x);
}, 500 * x);
});
}
test();
输出结果:
end
1
2
3
解答
原因
forEach 只支持同步代码,不会等待异步操作完成。参考 Polyfill 实现:
while (index < arr.length) {
callback(item, index); // 直接调用回调函数,不处理异步
}
forEach 只是简单执行回调函数,不会处理 async 函数返回的 Promise。
解决方案 1:for…of
async function test() {
let arr = [3, 2, 1];
for (const item of arr) {
const res = await fetch(item);
console.log(res);
}
console.log("end");
}
输出结果:
3
2
1
end
解决方案 2:for 循环
async function test() {
let arr = [3, 2, 1];
for (let i = 0; i < arr.length; i++) {
const res = await fetch(arr[i]);
console.log(res);
}
console.log("end");
}
关键点
forEach直接调用回调函数,不等待 Promise 完成for...of通过迭代器遍历,支持await暂停执行- 传统
for循环同样支持await forEach中使用break也无法中断遍历
目录