ES6 中 yield 的问题

${yield} 是如何执行的

我在学习 Generator 的时候看到一段不错的代码,自己改了改不知道如何去读,希望有人能解答一下,如下:

function* bar() {
  console.log('one');
  console.log('two');
  console.log('three');
  yield console.log('test');
  console.log(`1. ${yield}`);
  console.log(`2. ${yield}`);
  return 'result';
}
let barObj = bar();
barObj.next();
barObj.next('a');
barObj.next('b');

返回的结果为:

one
two
three
test
1. b
  • 第一次 next 的时候应该走到了 yield console.log('test')
  • 第二次传了一个 a 这个时候程序似乎没有执行
阅读 2.9k
3 个回答

你需要知道next传值与yield接收值并不是按顺序对应的,应该是:

  1. 第一个next传值没有yield接收;
  2. 第二个next传值由第一个yield接收;
  3. 第三个...由第二个...
  4. ...

另外,你可以在后面多调用两个next()看输出:

function* bar() {
  console.log('one');
  console.log('two');
  console.log('three');
  yield console.log('test');//第一个yield接收到第二个next传的a
  console.log(`1. ${yield}`);//第二个yield接收到第三个next传的b
  console.log(`2. ${yield}`);//第三个yield接收到第四个next传的c
  return 'result';
}
let barObj = bar();
barObj.next();
barObj.next('a');
barObj.next('b');
barObj.next('c');
barObj.next();

输出:

one
two
three
test
1. b
2. c
{value:undefined,done:true}

首先明确的是a执行了。

barObj.next(); //输出test
barObj.next('a'); //a给了第一个yield,但是没有使用
barObj.next('b'); //b给了第二yield,并输出1. b

自己又梳理了一下

我们可以把

barObj.next();
barObj.next('a');
barObj.next('b');

改为如下的形式,这样看起来更加的方便

console.log(barObj.next(), barObj.next('a'), barObj.next('b'));

上面的代码应该这么来读

首先要明白 console.log 的返回值是 undefined

next 1.
    console.log('one')...console.log('test');
    return { value: unfefined, done: false }
next 2.
    yield console.log('test') = 'a';
    ${ yield undefined } 写括号是为了方便看,其实没有括号
    return { value: undefined, done: false }
next 3.
    console.log(`1. ${'b'}`);
    return { value: undefined, done: false }
推荐问题
宣传栏