话很少少,进入正文。bash
首先来看这两道题:异步
// 定义一个fetch函数模拟异步请求
function fetch(x) {
return new Promise((resolve, reject) => {
console.log('aaa');
setTimeout(() => {
resolve(x)
}, 500 * x)
})
}
// 第一题:
function test() {
let arr = [3, 2, 1]
arr.forEach(async item => {
const res = await fetch(item)
console.log(res)
})
console.log('end')
}
test();
输出结果:3次aaa , end ,1 , 2 , 3
// 第二题:
async function test() {
let arr = [3, 2, 1]
for (const item of arr) {
const res = await fetch(item)
console.log(res)
}
console.log('end')
}
test();
输出结果:aaa , 3 , aaa , 2 , aaa , 1 , end
复制代码
为何一样是遍历,输出结果却不同呢?async
由于 for...of 内部处理的机制和 forEach 不一样,forEach 是直接调用回调函数,for...of 是经过迭代器的方式去遍历。函数
二者的处理机制:fetch
while (index < arr.length) {
// 也就是咱们传入的回调函数
callback(item, index)
}
复制代码
async function test() {
let arr = [3, 2, 1]
const iterator = arr[Symbol.iterator]() //for of会自动调用遍历器函数
let res = iterator.next()
while (!res.done) {
const value = res.value
const res1 = await fetch(value)
console.log(res1)
res = iterator.next()
}
console.log('end')
}
复制代码
可能有的读者会对aaa的输出位置有疑问,本文异步请求中涉及setTimeout,所以牵扯到JS引擎的执行机制(宏任务和微任务)。故在此很少加赘述了。ui