背景
我正在试验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 4和try块的剩余部分.
但为什么发电机跳过产量为7?
解决方法
它不会跳过yield 7.当你调用throw()时,控制流进入catch块,记录错误,然后继续执行,直到新的迭代器结果对象的下一个yield {value:7,完成:false}返回.
只是在你的代码中你没有console.log这个特定的结果对象.尝试:
console.log(myIterator.throw(new Error('Bullocks!')));
这在step 11 and 13 of the spec中解释:
- Resume the suspended evaluation of genContext using abruptCompletion as the result of the operation that suspended it. Let result be the completion record returned by the resumed computation.
- (…)
- Return Completion(result).