generator
让一个对象支持for...of遍历
for...of遍历方法一
const range = {
from: 0,
to: 10,
[Symbol.iterator]() {
return { // 第一次会使用current的值
current: this.from,
last: this.to,
next() { // 后续每次for...of都会调用next(),当done为true时候结束调用
if (this.current <= this.last) {
return {
done: false,
value: this.current++
}
}
return {
done: true
}
}
}
}
}
console.log([...range]) // (11) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]方法二
Async Iterator
为了使对象可以异步迭代:
我们需要使用
Symbol.asyncIterator取代Symbol.iterator。next()方法应该返回一个promise。我们应该使用
for await (let item of iterable)循环来迭代这样的对象
正如我们所看到的,其结构与常规的 iterator 类似:
为了使一个对象可以异步迭代,它必须具有方法
Symbol.asyncIterator(1)。这个方法必须返回一个带有
next()方法的对象,next()方法会返回一个 promise(2)。这个
next()方法可以不是async的,它可以是一个返回值是一个promise的常规的方法,但是使用async关键字可以允许我们在方法内部使用await,所以会更加方便。这里我们只是用于延迟 1 秒的操作(3)。我们使用
for await(let value of range)(4)来进行迭代,也就是在for后面添加await。它会调用一次range[Symbol.asyncIterator]()方法一次,然后调用它的next()方法获取值。
Iterator
Async Iterator
提供 iterator 的对象方法
Symbol.iterator
Symbol.asyncIterator
next() 返回的值是
任意值
Promise
要进行循环,使用
for..of
for await..of
Async generator
Async Iterator
总结
常规的 iterator 和 generator 可以很好地处理那些不需要花费时间来生成的的数据。
当我们期望异步地,有延迟地获取数据时,可以使用它们的 async counterpart,并且使用 for await..of 替代 for..of。
Async iterator 与常规 iterator 在语法上的区别:
Iterable
Async Iterable
提供 iterator 的对象方法
Symbol.iterator
Symbol.asyncIterator
next() 返回的值是
{value:…, done: true/false}
resolve 成 {value:…, done: true/false} 的 Promise
Async generator 与常规 generator 在语法上的区别:
Generator
Async generator
声明方式
function*
async function*
next() 返回的值是
{value:…, done: true/false}
resolve 成 {value:…, done: true/false} 的 Promise
在 Web 开发中,我们经常会遇到数据流,它们分段流动(flows chunk-by-chunk)。例如,下载或上传大文件。
我们可以使用 async generator 来处理此类数据。值得注意的是,在一些环境,例如浏览器环境下,还有另一个被称为 Streams 的 API,它提供了特殊的接口来处理此类数据流,转换数据并将数据从一个数据流传递到另一个数据流(例如,从一个地方下载并立即发送到其他地方)。
Last updated
Was this helpful?