深入浅出 Generator
概念基本
形式上,Generator 是一个函数,但具有两个区别于普通函数的特征:
function
关键字和函数名之间有一个星号(*)函数体内部使用
yield
表达式,定义不同的内部状态(yield 代表产出)
内涵上可以将其理解为一个状态机 + 遍历器对象
如下调用:
调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的内部指针。以后,每次调用遍历器对象的next
方法,就会返回一个有着value
和done
两个属性的对象。value
属性表示当前的内部状态的值,是yield
表达式后面那个表达式的值;done
属性是一个布尔值,表示是否遍历结束
yield
表达式
yield
表达式由于 Generate 函数返回的遍历器对象,只有调用 next 方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield 表达式就是暂停标志。
遍历器对象的 next 方法的运行逻辑如下:
(1)遇到 yield 表达式,就暂停执行后面的操作,并紧跟在 yield
后面的那个表达式的值,作为 Generate
返回的对象的 value
属性值
(2)下一次调用 next
方法时,再继续往下执行,直到遇到下一个 yield
表达式
(3)如果没有再遇到新的 yield 表达式,就一直运行到函数结束,直到 return
语句为止,并将 return
语句后面的表达式的值,作为返回的对象的 value
属性值
(4)如果该函数没有 return
语句,则返回的对象的 value
属性值为 undefined
需要注意的是,yield
表达式后面的表达式,只有当调用 next
方法、内部指针指向该语句时才会执行,因此等于 js
提供了手动的“惰性求值“的语法功能。
例如:
yield
后面的表达式 123 + 456
,不会立即求值,只会在 next
方法将指针移到这一句时,才会求值。
tips:yield 表达式只能用在 Generator 函数中
next 方法的参数
yield
表达式本身没有返回值,或者说总是返回 undefined
。next
方法可以带一个参数,该参数就会被当作一个 yield
表达式的返回值
上面代码先定义了一个可以无限运行的 Generate
函数 f
,如果 next
方法没有参数,每次运行到 yield
表达式,变量 reset
的值总是 undefined
。当 next
方法带一个参数 true
时,变量 reset
就被重置为这个参数(即 true
),因此 i
会等于 -1
,下一轮循环就会从 -1
开始递增。
简单使用
Generator
函数中的 yield
语句执行可以通过 next
顺序执行,yield
本身没有返回值,当 yield
语句用 next
执行时会返回 yield
语句返回的值。可以通过 next
传入值给 yield
,从而使它具有返回值
Last updated
Was this helpful?