在前端开发中,迭代是非常常见的操作。ES6 引入了迭代器和生成器,使得我们可以更加简单和方便地迭代一个集合。但是,对于异步集合,ES6 并没有提供像同步集合一样方便的迭代方法。在 ES12 中,新加入了 for await of 迭代器,为我们处理异步集合提供了更加优美的解决方案。
什么是异步集合?
异步编程是指将代码的执行顺序交给了 JavaScript 的事件循环。相信大家都很熟悉 Promise,Promise 是一个很常见的异步编程解决方案。Promise 在处理异步任务时,往往是返回一个 Promise 对象,并将异步任务的结果通过 Promise.resolve() 或 Promise.reject() 传递给 Promise 对象,由 Promise 对象负责在任务完成后通知事件循环。
而异步集合指的是一个尚未完成但具有朝向完成的趋势的集合对象,比如 Promise 数组和异步生成器等。由于无法事先得知集合内部每一项的完成时间,因此我们无法对其执行同步的迭代操作。
for await of 迭代器详解
在 ES12 中,我们可以使用 for await of 迭代器来处理异步集合。
for await (const item of someAsyncIterable) {
// 处理每个 item
}使用 for await of 迭代器的关键是,我们需要迭代的集合需要实现一个 next() 方法,在方法中返回一个 Promise,当 Promise resolve 后,返回一个 { value, done } 对象,其中 value 为当前迭代的值,done 表示迭代是否结束。
接下来,我们以一个例子详细看一下 for await of 的用法。
// www.javascriptcn.com code example
function delay(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(time)
}, time)
})
}
async function* generateAsyncValues() {
yield delay(1000)
yield delay(2000)
yield delay(3000)
}
(async function(){
for await (let item of generateAsyncValues()) {
console.log(item)
}
})()在上面的代码中,我们实现了一个异步生成器generateAsyncValues(),它每秒钟返回一个数字。我们使用 for await of 循环遍历所有异步生成器生成的数字,并打印在控制台上。
执行上面的代码,控制台将依次输出 1000、2000、3000 三个数字,这就是异步生成器返回的数字。
复合异步可迭代对象
在某些情况下,我们可能需要同时处理来自多个远程接口的异步数据集合。此时,我们可以使用 Promise.all() 方法将多个异步任务组合在一起,然后使用 for await of 迭代器来遍历所有组合在一起的数据。
// www.javascriptcn.com code example
const dataPromises = [
fetch('/data/1.json').then(res => res.json()),
fetch('/data/2.json').then(res => res.json()),
fetch('/data/3.json').then(res => res.json()),
]
async function* generateAsyncValues() {
yield await Promise.all(dataPromises)
}
(async function(){
for await (let item of generateAsyncValues()) {
console.log(item)
}
})()上面代码中,我们首先使用 Promise.all() 方法组合了三个 Promise,这里的 Promise 是以远程接口请求得到的 JSON 数据。随后,我们使用 yield 关键字将数据集合放入了一个异步生成器中。在最后的代码块中,我们使用 for await of 迭代器方式遍历生成器内的数据。
结语
使用 ES12 引入的 for await of 迭代器,在处理异步集合时提供了更优美的解决方案。通过上述介绍和代码示例的学习,相信大家可以更加深入地了解异步集合的概念和使用方法。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d6c5c1a941bf7134ca6308