JavaScript-生成器函数
生成器函数
JavaScript 依赖于单纯程执行模型,导致的问题是服务请求未完成前,UI 页面都在等待渲染状态,用户看到是空白页面。
生成器函数能生成一组值的序列,每个值的生成都是基于每次请求,并不同于标准函数那样立即生成。
yield 用于生成独立的值
1 | // 创建一个生成器函数 |
yield* 把执行权交给下一个生成器
1 | // 定义生成器一 |
for-of 循环取出生成器中生成的值序列,迭代器进行迭代的语法糖
1 | // 定义一个生成器,可生成 ingredient 序列 |
调用生成器,不会直接执行生成器,而是产生一个迭代器对象与生成器通信。迭代器对象暴露的最基本的接口是 next
,next
用来向生成器求一个值,从而控制生成器,遇到 yield
返回中间对象。多次循环,直至 {value: undefined, done: true}
生成器与迭代器工作流
flowchart TD invokeGenerator[调用生成器] -->|"Generator()"| iterator("迭代器 Iterator") iterator -->|"next()"| yield{生成器中是否还有yield?} yield -->|yes| Yes(" { value: 'cookie', // 结果值 done: false // 指示器 }") yield -->|no| No(" { value: undefined, // 结果值 done: true // 指示器 }") No -->|"done: ture"| End
生成器与迭代器通信
yield / next
1 | // 生成器传参 |
next 方法可以为等待中的 yield 提供值,所以第一个 next 方法传参无效,因为第一次执行生成器代码,没有等待中的 yield.
try-catch
迭代器通过 throw 方法向生成器抛出异常
1 | // 创建生成器 |
生成器的执行状态
1 | function* GeneratorFn(name) { |
执行上下文跟踪生成器函数
1 | // 创建一个生成器函数 |
调用生成器函数之前的应用状态
调用生成器函数之后的应用状态
生成函数执行之后
生成函数执行之后,generator 函数执行上下文出栈,但不被销毁,因为 iterator 保持着对 generator 函数执行上下文的引用
调用跌代器的 next 方法
1 | // 创建一个生成器函数 |
再次激活 Generator 执行上下文,并推入栈。从上一次执行位置之后继续执行
iterator.next() 执行之后
生成器挂起,返回生成器表达式的值与生成器状态值对象
最后再执行 iteractor.next()
没有 yield
表达式,return {value: undefined, done: true}
生成器进入结束状态。