我收到“太多递归”错误。我将尝试清楚地说明发生此问题的实际应用。
想象一下,该应用正在尝试调用网络服务来获取有关长货运列车内容的信息。有太多的信息,我们不能简单地调用网络服务,并告诉它一次性发送关于整列火车中每辆车的所有信息。相反,我们依次向网络服务询问每辆货车,当收到有关单个厢式车的信息时,我们更新页面然后要求下一辆车。
为了保持客户端响应,我们避免循环并使用array.shift()代替事件:
我们有一个活动:
$('body').bind('NextBoxCar', function( e, p) { getNexBoxCar(e,p); });
我们有一个函数可以从数组中删除第一个boxcarid并将其发送到webservice:
EDIT: BoxCarIds is not a global but inside a function
function() foo {
var BoxCarIds = [123, 222, 767, 1234, 9298, ... 999];
$('body').triggerHandler('NextBoxCar', BoxCarIds);
}
function getNextBoxCar(e, BoxCarIds) {
var id = BoxCarIds.shift();
// build an ajax request; omitted for brevity
$.ajax( {
.
. <snip>
.
success: function(data, textStatus, oHTTP ) {
UpdatePage(data, BoxCarIds);
}
});
}
当boxcar的数据从webservice返回时,ajax success-handler调用以下函数,该函数更新页面然后触发NextBoxCar事件。我相信这是递归问题发生的地方。
function UpdatePage(data, BoxCarIds) {
// update the page with data
.
. <snip>
.
// if there are still ids remaining in the array, we need to call the webservice again by firing the event
if (BoxCarIds.length > 0 ) {
$('body').triggerHandler('NextBoxCar', BoxCarIds);
}
}
如何避免递归问题?
由于
答案 0 :(得分:2)
您有BoxCarIds
作为全局变量,但您也将其作为参数传递给UpdatePage
和getNextBoxCar
。因此,当您在UpdatePage
或getNextBoxCar
内时,您正在操纵BoxCarIds
的本地版本,而不是全局版本!
从BoxCarIds
和UpdatePage
中删除参数getNextBoxCar
。那么你的代码应该可以正常工作。
以下是一个例子:
var x = 3;
function Eat(x)
{
x = 5;
}
alert(x); //alerts 3
Eat(x);
alert(x); //alerts 3
但是如果你从Eat中删除参数,你会得到:
var x = 3;
function Eat()
{
x = 5;
}
alert(x); //alerts 3
Eat(x);
alert(x); //alerts 5
答案 1 :(得分:2)
此处的递归部分对功能并不重要。这只是ajax调用的结果。您可以使ajax调用同步并将getNextBoxCar
更改为循环。但是,这仍然会使页面无法响应!
因此,我认为您可以使用setTimeout
调用UpdatePage方法来解决此问题。这应该打破递归并使页面响应。请参阅this jsFiddle example。
尝试更改为:
// build an ajax request; omitted for brevity
$.ajax( {
.
. <snip>
.
success: function(data, textStatus, oHTTP ) {
setTimeout( function() {
UpdatePage(data, BoxCarIds);
}, 0);
}
});
答案 2 :(得分:0)
我没有看到“编辑”按钮,因此我将不得不用答案回复建议。无法格式化代码以使其在评论中可读。
在问上述问题时我傻了。道歉。实际程序中的BoxCarIds不是全局的。该计划是这样的:
function getBoxCarIds(){
.
.
.
var BoxCarIds = data; // data is returned by webservice
$('body').triggerHandler('NextBoxCar', BoxCarIds); // kick things off
}
BoxCarIds数组的长度实际上在减少。当“货运列车”相当短时,程序运行良好。当列车很长时(例如140辆车),它只会遇到错误。
答案 3 :(得分:0)
在jquery 1.4.2中第1936行的FF 3.6.6中发生了“过多的递归”错误:
// Filter the functions by class
1929 if ( all || namespace.test( handleObj.namespace ) ) {
1930 // Pass in a reference to the handler function itself
1931 // So that we can later remove it
1932 event.handler = handleObj.handler;
1933 event.data = handleObj.data;
1934 event.handleObj = handleObj;
1935
1936 var ret = handleObj.handler.apply( this, arguments ); // ERROR HERE
1937
1938 if ( ret !== undefined ) {
1939 event.result = ret;
1940 if ( ret === false ) {
1941 event.preventDefault();
1942 event.stopPropagation();
1943 }
1944 }
1945
1946 if ( event.isImmediatePropagationStopped() ) {
1947 break;
1948 }
1949 }
1950 }