javascript 在此模式中抛出错误后,生成器函数能否继续执行?

mm9b1k5b  于 2022-12-17  发布在  Java
关注(0)|答案(2)|浏览(143)

These docs让我认为答案可能是肯定的-但我一直认为不是,我的测试也显示了同样的结果。
我之所以提出这个问题,是因为在我的项目中,一个生成器函数似乎只完成了一次,而我无法重新创建它,也找不到代码中的任何错误--所以我开始认为错误出在我的假设中。

function* someMethod(i) {
  try {
    yield i;
    throw new Error('error text');
    yield call(anotherMethod); // << This should never be executed, right?
  } catch (err) {
    console.error(err);
  }
zsohkypk

zsohkypk1#

当抛出错误时,生成器函数的执行将停止,生成器将关闭,错误将传播到调用代码。这是因为当抛出错误时,它中断了生成器函数中的正常执行流,并导致它提前终止。

drnojrws

drnojrws2#

你的“模式”是不完整的,所以我们无法知道还有什么在发生。是的,throw语句后面的注解所标记的那一行永远不会执行,但是catch代码块内部的那一行以及它后面的那几行将会执行--它们可以包含更多的yield表达式,这将暂停执行,并允许稍后继续执行:

function* someMethod(i) {
  try {
    yield 'start it up';
    yield 'This is not executed'; // if the previous line throws
  } catch (err) {
    yield 'but this is';
  }
  yield 'and so is this';
}
const gen = someMethod();
console.log(gen.next());
console.log(gen.throw());
console.log(gen.next());
console.log(gen.next());

这可以用来创建发电机,永远不会结束,总是可以继续,无论你在他们.throw()

function* ignoreErrors() {
  while (true) {
    try {
      yield;
    } catch(e) {}
  }
}

我们甚至可以构建生成器,您可以在上面调用.return(),而且它们不会停止:

function* forever() {
  try {
    yield;
  } finally {
    return yield* forever();
  }
}

或者不依赖于尾部递归(无论如何,尾部递归既没有被指定也没有被实现),但是更可怕的代码:

function* forever() {
  run: while (true) {
    try {
      yield;
    } finally {
      continue run;
    }
  }
}

相关问题