为什么这个生成器跳过try块之外的yield?

时间:2016-04-26 06:36:35

标签: javascript ecmascript-6 generator

背景

我正在试验Generator.prototype.throw()的工作原理并制作了这个例子:

var myGen = function *() {

    try{
        yield 1;
        yield 2;
        yield 3;
        yield 4;
        yield 5;
    }

    catch(err) {

        console.log(err);
    }

    yield 7;
    yield 8;
    yield 9;

}

var myIterator = myGen();

console.log(myIterator.next());
console.log(myIterator.next());
console.log(myIterator.next());

myIterator.throw(new Error('Bullocks!'));

console.log(myIterator.next());
console.log(myIterator.next());
console.log(myIterator.next());

在运行时导致以下结果:

{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
[Error: Bullocks!]
{ value: 8, done: false }
{ value: 9, done: false }
{ value: undefined, done: true }

问题

我可以理解,在发出错误后会跳过yield 4try块的剩余部分。

但为什么生成器会跳过yield 7

1 个答案:

答案 0 :(得分:9)

它不会跳过yield 7。当您调用throw()时,控制流进入catch块,记录错误,然后继续执行,直到下一个yield新迭代器结果对象{{1}返回。

只是在您的代码中,您不会{ value: 7, done: false }这个特定的结果对象。尝试:

console.log

step 11 and 13 of the spec中解释了这一点:

  
      
  1. 使用abruptCompletion恢复暂停的genContext评估,作为暂停它的操作的结果。设result为恢复计算返回的完成记录。
  2.   
  3. (...)
  4.   
  5. 退货完成(结果)。
  6.