如何捕获"超出最大调用堆栈大小"错误?

she*_*wen 3 javascript callstack try-catch

  try {
     requestAnimationFrame(function re(){
       re();
     })}
  catch (e){
       console.log(e);
     }
Run Code Online (Sandbox Code Playgroud)

我在控制台上尝试了上面的代码,它没有按预期工作.在我看来,虽然

 requestAnimationFrame(function re(){
       re();
     })}
Run Code Online (Sandbox Code Playgroud)

最终将触发一个错误,抛出的try是动画的id.如何捕获"超出最大调用堆栈大小"错误?

小智 7

超出错误的最大调用堆栈大小可以像任何其他错误一样被捕获:

try {
  function recur() { recur(); };
  recur();
} catch (ex) {
  console.log("caught " + ex);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下要做什么(超出调用堆栈大小)没有在ECMAScript规范中定义,但实际上,所有浏览器都会抛出可捕获的异常.但是,缺少规范不同的浏览器选择抛出不同类型的异常:我Error,RangeErrorInternalError.

代码中的问题与此无关.问题是你正试图捕捉你打电话时发生的异常requestAnimationFrame().但是你的re()函数不会在那一点上运行,它会在你请求的下一帧中运行.在里面re(),你可以包装递归调用re()并在那里捕获堆栈溢出异常:

requestAnimationFrame(function re(){
  try {
    re();
  } catch (ex) {
    console.log("caught " + ex);
  }
});
Run Code Online (Sandbox Code Playgroud)


Bin*_*ion 4

关于捕获最大堆栈大小超出错误的问题是我不确定它是如何工作的。浏览器唯一可以做的允许捕获错误的事情就是清空堆栈,然后运行下一个函数作为 catch 函数,但在那时(我认为浏览器甚至不能做到这一点)你会没有任何迹象表明您的代码在哪里损坏,因此您尝试运行的任何内容充其量都将是严重的错误。

另一个问题(这可能就是为什么没有浏览器有这个问题)是因为在错误发生后运行的大多数功能只是尝试以某种方式重新启动正常的 Web 功能。因为你不知道是什么出了问题,所以你无法阻止它再次发生,所以你最终会一次又一次地崩溃。这会让用户和浏览器对你的网页感到愤怒。

所以我想最好的办法就是确保你的代码没有无限循环并且能够顺利运行

关于堆栈大小及其工作原理的详细描述可以在这个问题的答案中找到

  • **这是不正确的。** 您正在描述处理内存不足错误,这是不同的。[**完全有可能捕获这些异常,它们的行为与典型异常没有任何不同,**请参阅我的答案](/sf/answers/3131323331/)。 (2认同)