代码:
// 延迟 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
原理一样,所以也能达到期望的效果。