Firefox 3.6.6和4.0 beta 1中的jQuery自定义事件和过多的递归错误

时间:2010-07-10 23:20:43

标签: jquery events recursion triggers

我收到“太多递归”错误。我将尝试清楚地说明发生此问题的实际应用。

想象一下,该应用正在尝试调用网络服务来获取有关长货运列车内容的信息。有太多的信息,我们不能简单地调用网络服务,并告诉它一次性发送关于整列火车中每辆车的所有信息。相反,我们依次向网络服务询问每辆货车,当收到有关单个厢式车的信息时,我们更新页面然后要求下一辆车。

为了保持客户端响应,我们避免循环并使用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);

     }


 }

如何避免递归问题?

由于

4 个答案:

答案 0 :(得分:2)

您有BoxCarIds作为全局变量,但您也将其作为参数传递给UpdatePagegetNextBoxCar。因此,当您在UpdatePagegetNextBoxCar内时,您正在操纵BoxCarIds的本地版本,而不是全局版本!

BoxCarIdsUpdatePage中删除参数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 }