JavaScript生成器的throw()方法如何推进迭代器?

4
我知道next()方法的用法,它将迭代器推进到yield关键字的下一个位置,并返回包含yield表达式结果的对象,如下所示:
yield double(40); => 调用iterator.next()将返回类似于 {done:false, value:80} 的东西
然而,我不太清楚throw()方法是否也会推进迭代器并返回下一个yield的表达式,除了将异常抛入生成器。文档说得像这样:
throw()方法通过将错误抛入生成器来恢复生成器的执行,并返回一个包含两个属性done和value的对象。
当我们调用iterator.throw()时,它是否会将异常抛入生成器(异常正确捕获)并推进到下一个yield关键字并返回yield表达式的结果?
如果需要,在此贴中包含代码片段以演示这一点,请告诉我,因为这是我在Stackoverflow上的第一篇文章。
谢谢!!!
1个回答

9

它确实将生成器从收到错误的yield推进。然而,由于throw在yield点引发异常,除非生成器代码准备捕获并吞噬异常,否则生成器将不会恢复并完成(done设置为true),将未捕获的异常冒泡到迭代器调用站点。

这里有一个简单的演示,请注意genDrunk的呕吐;) -

function* genSober() {
  while(true) {
    try {
       yield 42;
    } catch(e) {
      console.log("I don't drink at work!");
    }
  }
}

var g = genSober();
console.log(g.next());
// { value: 42, done: false }
g.throw("Have some wine...");
console.log(g.next());

function* genDrunk() {
  while(true) {
    yield 42;
  }
}

g = genDrunk();
console.log(g.next());
try {
  g.throw("Have some wine...");
}
catch (e){
}
console.log(g.next());


你的回答如果有更详细的评论会更有价值。 - Mega Proger
谢谢您的反馈,@mega-proger。我尝试做了一个描述性的例子来展示这个主题。您能建议我应该详细说明什么吗? - hazardous

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接