ES9 异步操作集合遍历
// 异步任务
function Gen(time) {
return new Promise((resolve, reject) => {
setTimeout(function () {
resolve(time)
}, time)
})
}
async function test() {
let arr = [Gen(2000), Gen(100), Gen(3000)]
for (let item of arr) {
console.log(Date.now(), await item.then(console.log))
}
}
test()
//1574145134469 Promise {<pending>}__proto__: Promise[[PromiseStatus]]: "resolved"[[PromiseValue]]: undefined
// 1574145134470 Promise {<pending>}
// 1574145134471 Promise {<pending>}
//100
//2000
//3000
在上述遍历的过程中可以看到三个任务是同步启动的,输出上也不是按任务的执行顺序输出的,这显然不太符合我们的要求。
for...of... 遍历同步操作,如果集合里有异步操作,for...of...无法拿到正确结果。
// 异步任务
function Gen(time) {
return new Promise((resolve, reject) => {
setTimeout(function () {
resolve(time)
}, time)
})
}
async function test() {
let arr = [Gen(2000), Gen(100), Gen(3000)]
for await (let item of arr) {
console.log(Date.now(), item);
}
}
test()
// 1574145729887 2000
// 1574145729888 100
// 1574145730888 3000
自定义数据结构不支持遍历,如果要使其支持遍历需要在对象上挂载 [Symbol.iterator] 属性,需遵循可迭代协议和迭代器协议。那么在自定义数据结构中,要遍历的对象有异步操作,应该怎么处理?
let obj = {
count: 0,
Gen (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve({ done: false, value: time })
}, time)
})
},
[Symbol.asyncIterator] () {
let self = this
return {
next () {
self.count++
if (self.count < 4) {
return self.Gen(Math.random() * 1000)
} else {
return Promise.resolve({
done: true,
value: ''
})
}
}
}
}
}
async function test () {
for await (let item of obj) {
console.log(Date.now(), item)
}
}