美文网首页
笔记:JavaScript关键字yield

笔记:JavaScript关键字yield

作者: chenhong_f1e2 | 来源:发表于2018-09-27 09:55 被阅读0次

    本文摘录及参考自:
    1. function*- JavaScript | MDN - Mozilla
    2. yield - JavaScript | MDN - Mozilla
    3. yield* - JavaScript | MDN - Mozilla
    4. Koa 框架教程
    5. yield 原理篇
    6. 代码写了那么多,你搞明白yield是个啥没?
    7. yield 和 yield*

    1. yield关键字的定义

    yield关键字用来暂停和恢复一个生成器函数。那么什么是生成器函数呢?

    1.1 什么是生成器函数

    function* generator(i) {
      yield i;
      yield i + 10;
    }
    

    如上代码所示,function*这种声明方式(function关键字后面跟一个星号)会定义一个生成器函数。

    1.2 生成器函数的功能

    生成器函数在执行时能暂定,后面又能从暂定处继续执行。调用一个生成器函数并不会马上执行它里面的语句,而是返回一个Generator对象。当这个对象的next()方法被首次(后续)调用时,其内的语句会执行到第一个(后续)出现yield的位置,yield后紧跟迭代器要返回的值。

    例1:

    function* generator(i) {
      yield i;
      yield i + 10;
    }
    var gen = generator(10);
    console.log(gen.next().value); // 输出10, gen.next()的值是{value:10,done:false}
    console.log(gen.next().value); // 输出20, gen.next()的值是{value:20,done:false}
    console.log(gen.next().value); // 输出undefined, gen.next()的值是{value:undefined,done:true}
    console.log(gen.next());    // 后续的无论多少次调用 gen.next(),输出均是{value:undefined,don:true}
    

    1.3 yield关键字的功能

    yield关键字可以被认为是一个基于生成器版本的return关键字。yield也必须在Generator函数中才有意义,脱离了Generator就没意义了啊,这就像说“鲨鱼是用来在海里面消灭傻瓜鱼的”现在你把鲨鱼丢到陆地上,请问它有啥意义?yield返回的对象有两个属性,value和done。value属性是对yield表达式求值的结果,而done是false,表示生成器函数尚未完全完成。一旦遇到yield表达式,生成器的代码将会被暂停运行,直到生成器的next()方法被调用。每次调用生成器的next()方法时,生成器都会恢复执行,直到达到以下某个值:

    • yield,导致生成器再次暂定并返回生成器的新值 。下一次调用next()时,在yield之后紧接着的语句继续执行
    • throw,用于从生成器中抛出异常。这让生成器完成停止执行,并在调用者中继续执行,正如通常情况下抛出异常一样。
    • 到达生成器函数的结尾/return 语句:在这种情况下,生成器的执行结束,并且返回对象的done值为true

    2. yield 和 yield* 的区别

    yield* 一般用来在一个 generator 函数里“执行”另一个 generator 函数,并可以取得其返回值。用一个例子说明其用途

    例1:

    function* outer() {
        yield 'begin';
        yield inner(); //如果替换成yield* inner()呢?
        yield 'end';
    }
    
    function* inner() {
        yield 'inner';
    }
    
    var it = outer(), v;
    
    v = it.next().value;
    console.log(v);            // -> 输出:begin
    
    v = it.next().value;
    console.log(v);            // -> 输出:{inner对象},实际想要 inner
    console.log(v.toString()); // -> 输出:[object Generator]
    
    v = it.next().value;
    console.log(v);            // -> 输出:end
    

    上面这段代码中, yield inner()比较容易理解,就是返回了另外一个对象{value:新的Generator迭代器,done:false}。 如果想要使用新的迭代器中的内容,还需要再次调用它的next方法

    v = it.next().value;
    console.log(v);            // -> 输出:{inner对象}
    console.log(v.toString()); // -> 输出:[object Generator]
    console.log(v.next());     // ->输出:{value:"inner",done:false}
    
    

    这样的使用太麻烦了,可以使用yield*

    
    function* outer() {
        yield 'begin';
        yield* inner(); //如果替换成yield* inner()呢?
        yield 'end';
    }
    
    function* inner() {
        yield 'inner';
    }
    
    var it = outer(), v;
    
    v = it.next().value;
    console.log(v);            // -> 输出:begin
    
    v = it.next().value;
    console.log(v);            // -> 输出:inner
    
    v = it.next().value;       
    console.log(v);            // -> 输出:end
    

    可以看到 yield* inner()直接返回了 inner()迭代器中第一个yield返回的对象。

    相关文章

      网友评论

          本文标题:笔记:JavaScript关键字yield

          本文链接:https://www.haomeiwen.com/subject/ofazwftx.html