由来我们知道React中有一个特性ErrorBoundary,它可以帮助我们在组件发生错误时显示“错误状态”的UI。为了实现此功能,必须捕获错误。所以在React源码中,所有的用户代码都被包裹在一个方法中执行。类似如下:functionwrapper(func){try{func();}catch(e){//...handlingerrors}}比如componentDidMount被触发时:wrapper(componentDidMount);一切都很完美,但React是世界一流的前端框架,拥有广泛的受众,一切都应该做到极致。这不,有人提出了一个问题:像这样在trycatch中执行用户代码会使浏览器调试工具的Pauseonexceptions失效。PauseonexceptionsinvalidationPauseonexceptions的来龙去脉是什么?它是浏览器调试工具源代码面板的一个功能。启用该功能后,如果在运行时遇到会抛出错误的代码,代码的执行会自动停在这一行,就像在这一行打了断点一样。例如,执行以下代码并启用该功能:leta=c;代码的执行将在此行暂停。这个特性可以很方便的帮助我们找到哪里出现了未捕获的错误。但是,当React将用户代码包装在trycatch中时,即使代码抛出错误,也会被捕获。Pauseonexceptions不能在抛出错误的用户代码处暂停,因为错误已经被React捕捉到了。除非我们进一步打开Pauseoncaughtexceptions。启用此功能可使代码在捕获到的错误发生时暂停。如何解决对于用户来说,我在componentDidMount中写的代码明明没有捕获到错误,但是出现错误时Pauseonexceptions却失败了,真是让人费解。因此,在生产环境中,React继续使用trycatch来实现wrapper。在开发环境中,为了更好的调试体验,需要重新实现一套trycatch机制,包括以下功能:通过用户代码,使PauseOn异常不会使这个看似矛盾的功能失效,React是如何巧妙地实现它的?如何“捕获”错误让我们从第一点开始:捕获用户代码抛出的错误。但是你不能使用trycatch,因为它会使Pauseonexceptions失效。解决方法是:监听窗口的错误事件。根据GlobalEventHandlers.onerrorMDN[1],该事件可以监听两种类型的错误:js运行时错误(包括语法错误)。窗口会触发ErrorEvent接口的错误事件。资源(如或
