返回

Generator里抛错,咋办?

前端

抛出错误是JavaScript里非常重要的一环,很多地方都可能用到。比如,你可以在函数里抛出错误。但是,你是否想过如何在Generator里抛出错误呢?

Generator抛错

Generator抛出错误的方法很简单,它只需要用到一个内建的方法:generator.throw。我们通过一个例子来看下如何使用:

function* generate() {
  try {
    yield 1;
    yield 2;
  } catch(e) {
    console.error('Caught Error:', e.message);
  }
}

const g = generate();
g.next(); // 1
// 此时,g.next()没有被调用,它的状态仍是"等待"状态("paused" state)。
// 以下代码块将向Generator抛出一个Error对象。
g.throw(new Error('I am an error.'));
g.next(); // Caught Error: I am an error.

代码的功能很简单,它先定义了一个Generator函数generate。在Generator里,我们用try-catch块捕获了错误。然后,我们实例化了一个Generator对象g

现在,我们调用g.next(),得到了第一个yield表达式(1)的值。你可能会想,g.next()已经调用完了,我们应该得到了Generator的最终返回值undefined了。但事情并非如此,Generator并没有执行完。这是因为Generator里仍有未执行的代码。

也就是说,此时,Generator g.next()没有被调用,它的状态仍是"等待"状态("paused" state)。

此时,我们调用了g.throw()方法,向Generator抛出了一个Error对象。然后,我们再次调用g.next()方法,此时,Generator会捕获到这个错误并将其打印出来。

捕获错误

从上面的例子我们可以看到,Generator里抛出的错误可以通过generator.throw()方法捕获。

在实际应用中,我们还可以用async/await来捕获Generator里抛出的错误。我们来看一个例子:

async function main() {
  try {
    const g = generate();
    const result = await g.next(); // 1
    await g.next(); // 此时,程序会抛出一个错误
  } catch(e) {
    console.error('Caught Error:', e.message);
  }
}
main(); // Caught Error: I am an error.

在上面的例子中,我们用async/await来调用Generator函数generate()。当Generator函数抛出错误时,我们用try-catch块来捕获这个错误。

Generator的状态

在Generator里抛出错误时,Generator的状态会发生变化。我们可以通过g.state属性来获取Generator的状态。

Generator的状态有以下几种:

  • "executing":Generator正在执行。
  • "paused":Generator暂停执行,等待下一个yield表达式或return语句。
  • "terminated":Generator已经执行完毕。
  • "closed":Generator已经关闭。

当Generator里抛出错误时,Generator的状态会从"executing"变为"closed"

调试Generator

我们可以用调试工具来调试Generator。在Chrome浏览器中,我们可以使用debugger语句来设置断点,然后使用Chrome DevTools来调试Generator。

在调试Generator时,我们可以使用g.state属性来查看Generator的状态。我们还可以使用g.next()g.throw()方法来控制Generator的执行。

总结

在本文中,我们介绍了如何在Generator里抛出错误。我们还介绍了如何捕获Generator里抛出的错误。最后,我们介绍了Generator的状态以及如何调试Generator。