代码:
// 延迟 num 秒后 打印 num
const say = async (num) => {
console.log(num, 'begin:')
await new Promise(resolve => {
setTimeout(() => {
console.log(num)
resolve()
}, num * 1000)
})
}
const nums = [2, 1]
// 遍历 nums 打印
async function for_Result() {
for (let n of nums) {
await say(n)
}
}
// 遍历 nums 打印
function forEach_Result() {
nums.forEach(async n => {
await say(n)
})
}
// 思考分别调用下面两个方法的结果:
// for_Result()
// forEach_Result()
结果:
// for_Result()
// 2 begin:
// 1 begin:
// 1
// 2
// forEach_Result()
// 2 begin:
// 1 begin:
// 1
// 2
解析:
两个遍历方法分别使用了 for of 和 forEach 循环数组,并使用 await等待异步方法的执行。
期望的都是实现同步执行,但是forEach并没有按照预期的去等待 say() 方法执行完毕。
难道forEach中的 await没有生效?
其实两种遍历并执行 say() 的方式是有区别的:
for of会在遍历到每个元素后,执行say()方法。
而forEach在遍历每个元素后,执行的是该方法接收的回调函数方法,然后在回调中,执行say()方法。
forEach方法内部调用 回调函数 时,并没有使用await修饰,所以回调方法并不会等待上一个回调执行完毕。
内部的 await 也就失去了意义。
同理for()循环和for of原理一样,所以也能达到期望的效果。
本文探讨JavaScript中for...of与forEach循环结合await使用时的不同行为。for...of循环能确保异步操作按顺序执行,而forEach中的await却无法达到相同效果。文章详细解析了两者的工作原理及为何forEach不能正确等待异步方法执行完毕。
443






