• 简介
  • 正文
  • 思考

    简介

    Generator 是ES6新增的一种函数,可以看做一个状态机

    通常我们通过Generator函数来实现一些异步操作

    正文

    定义一个Generator函数需要在function关键字后加一个*号

    1. function *f() {
    2. yield 1
    3. yield 2
    4. }
    5. let a = f()
    6. a.next() // {value: 1, done: false}
    7. a.next() // {value: 2, done: false}
    8. a.next() // {value: undefined, done: true}
    9. a.next() // {value: undefined, done: true}

    显然我们定义个一个叫做f的Generator函数,那么f可以看做是一个状态机

    f的内部我们用 yield 关键字定义了两个 状态

    然后我们通过f()执行这个函数,与普通函数不同的是,Generator函数执行后,

    得到的结果并不是函数的返回值,而是而是一个代表其内部状态的Iterator

    Iterator我们之前已经介绍过了,是一个通用的遍历器接口,我们可以调用它上面的next方法得到其内部的值

    yield 命令用在Generator函数体中,与return类似,停止执行函数并把它后面的表达式的值返回

    yield 把Generator函数体划分成一块一块来执行,每次调用next方法,都会使函数继续向下执行,直到遇见下一个 yield 并把值放在value里返回

    如果后续再没有其他 yield 或return 就把done字段置为true,代表全部的状态都已运行完毕

    正常情况下我们不会手动去一次次调用next查看结果,而是使用 for...of 循环:

    1. function *f() {
    2. yield 1
    3. yield 2
    4. }
    5. for(let x of f()){
    6. console.log(x)
    7. }
    8. // 1 2

    关于Generator的细节知识点很多,比如next还可以传入参数影响Generator函数内部状态等等

    不过时至今日(17年6月),Generator在开发中的应用已经很少了,这里不再为新手介绍其他知识

    主流的异步方案已经逐渐成型,目前我们使用Promise和Async来解决异步问题

    思考

    这部分内容希望你都可以手动敲一遍,独立思考

    尝试写出一个表示斐波那契数列的Generator函数

    函数接收一个参数,代表生成的斐波那契数列的长度

    1. function* fib(length){
    2. // 做一些操作,然后使用yield返回每一步的结果
    3. }
    4. for(let x of fib(7)){
    5. console.log(x)
    6. }
    7. // 输出 [1, 1, 2, 3, 5, 8, 13]