JavaScript Iterator 与 Generator
Iterator 迭代器
为各种数据结构提供一个统一的迭代方法, Iterator 迭代器主要使用 for…of 迭代
ES6 规定,默认的 Iterator 接口部署在数据结构的 Symbol…iterator 属性,或者说,一个数据结构只要具有 Symbol.iterator()属性,就可以认为是"可遍历的”(iterable)。Symbol…iterator 属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。
原生默认具备 Iterator 接口的数据结构如下。
-
Array
-
Set
-
Map
-
String
-
arguments 对象
-
NodeList 对象
如果一个对象具有 [Symbol.Iterator] 方法, 那么我们可以说它实现了迭代器, 是一个可迭代对象
迭代器需要返回一个函数, 此函数的返回值包含一个 next 函数, next 函数返回值有两个属性, 分别为 value 和 done
1 | const obj = { |
实现了 [Symbol.Iterator] 方法的对象就可以使用 for...of 循环了
Generator 生成器函数
Generator 函数是 ES6 提供的一种异步编程解决方案
Generator 函数是一个状态机,封装了多个内部状态。执行 Generator 函数会返回一个迭代器对象,也就是说,Generator 函数除了状态机,还是一个迭代器对象生成函数。返回的迭代器对象,可以依次遍历 Generator 函数内部的每一个状态。
1 | function* gen() { |
yield 表达式的作用是暂停生成器函数的执行,并在该位置上将控制权交回给调用方,等到再次调用该生成器对象的 next() 方法时继续执行。
!!! yield 表达式返回值取决于下一个 next() 方法中传入的参数。
在执行 g.next(1) 时,生成器函数会一直执行到第一个 yield 表达式处,然后暂停,将"你好"返回给调用者,并在等待下一次 next() 方法的执行。由于第一个 yield 表达式的返回值并不需要接收外部传递进来的任何值,因此 res1 变量就没有被赋值,也就是被忽略了。
配合 promise 实现异步操作
1 | const pro = num => { |
async/await 只是这种操作的语法糖
异步迭代器
如果 Generator 函数前面加了 async, 那么这个函数就叫做异步生成器, 异步生成器生成的叫做异步迭代器.
异步迭代器的.next 方法返回一个 promise 对象,这个 promise 对象的结果会包含 value 和 done 两个属性.
如果.next 对应的 yield 后面是普通对象, 那么这个 promise 会立刻 resolve.
如果 yield 后面是一个 promise 对象, 那么.next 返回的 promise 被 resolve 的时机是 .next 对应的 yield 后面的 promise 状态变为 resolve 的时候.
yield 后的 Promise 对象 resolve 之前,代码会暂停执行, 所以如果同步调用多个.next, 异步迭代器内部也会按照顺序执行.
可以使用for await (item of 异步迭代器) 来迭代异步迭代器
1 | const timer = (time: number) => { |
JavaScript Iterator 与 Generator
https://cuijunyu.win/20230427/JavaScript-Iterator-与-Generator/