Firefox 中的“太多递归”错误只是有时出现吗?

新手上路,请多包涵

我有一个非常简单的事情,我正在用 javascript 做,基本上只有有时 javascript 会给我一个“递归太多”的错误。

有问题的代码:

 if(pageLoad===undefined){
  var pageLoad=function(){};
}
var pageLoad_uniqueid_11=pageLoad;
var pageLoad=function(){
  pageLoad_uniqueid_11();
  pageLoad_uniqueid_12();
};
var pageLoad_uniqueid_12=function(){
 alert('pageLoad');
};

$(document).ready(function(){
   pageLoad();
});

(是的,我知道有更好的方法来做到这一点。虽然这很难改变,尤其是因为没有显示的 ASP.Net 部分回发)。

无论如何,当发生太多递归错误时,它会继续发生,直到我重新启动 Firefox。当我重新启动 Firefox 时,它又一切正常。我该如何解决?

我也做了一个 jsbin例子

更新

好的,我已经找到了如何在我们的代码中可靠地重现它,但它不适用于 jsbin 示例。如果我创建一个新选项卡并转到同一页面(有两个具有相同地址的选项卡),然后刷新第一个选项卡 两次,那么我会始终收到此错误。我们没有使用任何类型的会话或我能想到的任何其他可能导致此类问题仅发生在一个选项卡中的东西!

Update 2 不像我想象的那么可靠,但它肯定只在同一页面的多个选项卡打开时才会发生。它会在打开的选项卡之一的每几次重新加载中发生

我还更新了我的代码以在 pageLoad(if 语句)最初未定义和最初定义时显示警报。不知何故,两个警报都出现了。此代码不会在呈现的页面中重复,并且不可能被调用两次。它位于顶级脚本元素中,没有被函数或任何东西包围!我的代码最终看起来像

if(pageLoad===undefined){
  var pageLoad=function(){};
  alert('new');
} else {
  alert('old');
}

原文由 Earlz 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 264
2 个回答

有问题的代码—— _就其本身而言_—— 永远不会 导致无限递归问题——没有函数语句,所有函数对象都急切地分配给变量。 (如果 pageload 首先是未定义的,它将被分配一个无操作函数,见下一节。)

我怀疑还有其他代码/事件触发了该行为。 可能 导致它的一件事是如果脚本/代码在页面生命周期内被触发 _两次_。第二次 pageload 不会undefined,保持原来的值,如果是调用另外两个函数的函数,会导致无限递归。

我会建议清理该方法——并且由并发症引起的任何问题都会消失 ;-) 期望的意图是什么?

快乐的编码。

原文由 user166390 发布,翻译遵循 CC BY-SA 3.0 许可协议

这只是其他人试图在他们的代码中寻找类似的“太多递归”错误的一些附加信息。看起来像 firefox(作为一个例子)在这个例子中在大约 6500 个堆栈帧深度处得到太多的递归: function moose(n){if(n%100 === 0)console.log(n);moose(n+1)};moose(0) 。类似的例子可以看到 5000 到 7000 之间的深度。不确定决定因素是什么,但函数中的参数数量似乎大大降低了堆栈帧深度,在该深度处出现“太多递归”错误。例如,这只会达到 3100:

 function moose(n,m,a,s,d,fg,g,q,w,r,t,y,u,i,d){if(n%100 === 0)console.log(n);moose(n+1)};moose(0)

如果您想解决这个问题,您可以使用 setTimeout 来安排迭代以从调度程序(重置堆栈)继续。这显然只有在您不需要从调用中返回某些内容时才有效:

 function recurse(n) {
  if(n%100 === 0)
    setTimeout(function() {
      recurse(n+1)
    },0)
  else
    recurse(n+1)
}

在 ECMAScript 6 中适当的尾调用将解决某些情况下的问题,您确实需要从这样的调用中返回一些东西。在那之前,对于深度递归的情况,唯一的答案是使用迭代或我提到的 setTimeout 方法。

原文由 B T 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题