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/