generator 和 yield

yield 的使用

 

generator 生成器javascript

yield 能够使生成器返回屡次 
我习惯于从表象推测,不喜欢官方文档,写的字都认识,结果变成句子以后,就一句都看不懂java

因此先举一个例子来看一下这个东西怎么玩儿

如今要生成自增的id函数

传统写法spa

var public_id = 0;
    function idUp () {
      public_id++;
    }
    idUp() // 须要新id时,调用 idUp ,使外部的变量+1 ,无论是使用变量,仍是把id当作参数传入函数,函数内部没法保存id的当前状态(意思就是,若是没有外部变量也没有传参,函数就不知道id如今是多少).

使用生成器code

function* idUp () {
      let id = 0;
      while (true) {
        yield id
        id++;
      }
    }

    var addId = idUp();
    var newId = addId.next().value; // 须要新id时,使用 addId.next().value, 咱们无需关心外部是否有id,由于id的状态在函数里面

注意两种方式的不一样之处。对象

 

传统写法须要一个全局变量来保存id的状态,而使用 生成器 状态保存在生成器中(就这样理解吧,使用生成器的时候,就不须要定义全局变量了存储id了)。blog

你们也许会有疑问,使用 while(true) 都死循环了,这个 生成器真的能用么? 实则yield 会使 生成器暂停,一直到调用next()才会继续执行函数,直到遇到下一个yield或者returnip

写个简单的 生成器的例子来看一下文档

function *example () {
      let a = 0;
      console.log('第一次输出时a的值', a);
      yield a;
      a++;
      console.log('第二次输出时a的值', a);
      yield a;
      a++;
      console.log('第三次输出时a的值', a);
      return a;
    }

    var doExample = example(); 
    // 此时并不会输出 , 我的理解是, 生成器在当作函数执行的时候,实际上是返回了一个 生成器对象,或者说盒子比较恰当,生成器里面的真正须要执行的代码被放到了这个盒子里面。
    console.log(doExample); 
    // 输出 example {<suspended>}
    console.log(doExample.next()); 
    // 输出 “第一次输出时a的值 0 ”  和 {value: 0, done: false}
    console.log(doExample.next()); 
    // 输出 “第二次输出时a的值 1 ”  和 {value: 1, done: false}
    console.log(doExample.next()); 
    // 输出 “第三次输出时a的值 2 ”  和 {value: 2, done: true}
    console.log(doExample.next()); 
    // 输出  {value: undefined, done: true}

以上代码主要就是看一下 生成器的执行流程,主要是 经过这段代码来理解这样两个概念generator

 

1.yield 能够暂停生成器

2.next 继续执行生成器直到 遇到下一个yield或者return

如今能够理解上面使用whil(true)了,可是并不会致使死循环,由于程序的执行实际上是控制在 生成器的next手里。

另一个须要 特别说一下的知识点是 每次执行next返回的对象里面 的 done 表明了生成器是否执行完成。能够理解为后面是否还有yield 若是还有yield,则 done:false 若是没有yield了,则为 true

而且,当生成器执行到末尾的时候,既 done:true 的时候,再次执行 next ,并无任何输出,且 value 变成了 undefined。这里为啥是 undefined 。再写一个例子。

function *test () {
      let a = 0;
      yield;
      a++;
      yield a;
      a++;
      return a;
    }
    var doTest = test();
    console.log(doTest.next());
    // 输出 {value: undefined, done: false}
    console.log(doTest.next());
    // 输出 {value: 1, done: false}
    console.log(doTest.next());
    // 输出 {value: 2, done: true}
  
console.log(doTest.next());
  // 输出 {value: undefined, done: true}
 

比较和上一个例子的区别,第一次输出的 value 的值是 undefined ,由于代码中 yield 后面什么都没有。第二次value的值是1,由于代码中yield后面接了 a。 意思就是value里面的值是 yield 后面的东西。

因此,最后输出 undefined 是否是就理解了 (由于代码都跑完了,已经没有yield了,天然就不会再有值了,value天然就是空)

好了就说这么多了,还有更多坑,你们有兴趣的能够本身去踩踩。

。。。。

相关文章
相关标签/搜索