es6 yield

    function* dataConsumer() {
      console.log('Started');
      console.log(`1. ${yield}`);
      console.log(`2. ${yield}`);
      return 'result';
    }

    let genObj = dataConsumer();
    console.log(genObj.next());//[1]
    console.log(genObj.next('a'));//[2]
    console.log(genObj.next('b'));//[3]

请问上面代码是怎么一个执行顺序dataConsumer里面的第二个和第三个里的yield前面没有 类似yield 222之类的,,它是怎么执行的?谢谢

阅读 3.3k
3 个回答

yield语句是暂停执行的标记,每次调用next方法,执行到下一个yield之前。
因而,yield 222并不是一定要求的格式。
就像我们常常写的 return 222,函数返回值是222,而同样return;函数返回值是undefined。这是一样的道理。
因为此处 yield后面并没有跟返回值,所以genObj.next()返回值是Object {value: undefined, done: false}

遍历器对象的next方法的运行逻辑如下。

(1)遇到yield语句,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield语句。

(3)如果没有再遇到新的yield语句,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。

(4)如果该函数没有return语句,则返回的对象的value属性值为undefined。

阮一峰EMCAScript入门

function* dataConsumer() {
    console.log('Started');
    console.log(`1. ${yield}`);
    console.log(`2. ${yield}`);
    return 'result';
}
let genObj = dataConsumer();
//1. 创建一个generator实例

console.log(genObj.next());
//2. 开始执行dataConsumer,输出'Started',遇到yield,暂停执行dataConsumer,
//   开始执行本行的console.log为{ value: undefined, done: false }

console.log(genObj.next('a'));
//3.执行 genObj.next('a'),线程交还给dataConsumer,从上次暂停的地方开始,输出1.a,继续执行,遇到第二个yield,暂停
//  开始执行本行的console.log为{ value: undefined, done: false }

console.log(genObj.next('b'));
//4.执行 genObj.next('b'),线程交还给dataConsumer,输出2.b,继续执行,遇到return,返回‘result’,结束dataConsumer
//  执行本行的console.log,结果为{ value: 'result', done: true } 全部结束

yield后面没有值就会返回一个undefined

yield用作暂停的占位符,你这里的执行顺序是这样的:

genObj.next('a') // Started, {value: undefined, done: false}
genObj.next('b') // 1. b, {value: undefined, done: false}
genObj.next('c') // 2. c, {value: "result", done: true}

第一个next相当于init生成器,然后yield作为参数占位符,同时是生成器函数的暂停符,但是没有yield 222,所以value都是undefined,直到最后return 'result'value都是'result'

图片描述

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进