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

发布于 2024-09-08 23:02:06 字数 1383 浏览 1 评论 0原文

我收到“太多递归”错误。我将尝试对发生此问题的实际应用程序进行清晰的模拟。

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

为了保持客户端响应,我们避免循环并使用 array.shift() 的事件:

我们有一个事件:

$('body').bind('NextBoxCar', function( e,  p) { getNexBoxCar(e,p);  });

我们有一个函数,可以从数组中删除第一个 boxcarid 并将其发送到 Web 服务

 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 从 Web 服务返回后,ajax 成功处理程序调用以下函数,该函数更新页面,然后触发 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);

     }


 }

如何避免递归问题?

谢谢

I am getting a "too much recursion" error. I will try to give a clear analog to my actual application where this problem is occurring.

Imagine that the app is trying call a webservice to get information about the contents of a very long freight train. There is so much information that we cannot simply invoke the webservice and tell it to send down everything all at once about every car in tthe entire train. Rather, we ask the webservice about each freight-car in turn, and when the info about a single boxcar is received, we update the page and then ask for the next car.

To keep the client responsive, we avoid a loop and use events with array.shift() instead:

We have an event:

$('body').bind('NextBoxCar', function( e,  p) { getNexBoxCar(e,p);  });

We have a function that removes the first boxcarid from the array and sends it to the 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);
     }
   });

 }

When the data for the boxcar comes back from the webservice, the ajax success-handler invokes the following function, which updates the page and then fires the NextBoxCar event. I believe this is where the recursion problem is happening.

 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);

     }


 }

How to avoid the recursion problem?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

樱花坊 2024-09-15 23:02:06

这里的递归部分对于功能来说并不重要。这只是 ajax 调用的结果。您可以使 ajax 调用同步并将 getNextBoxCar 更改为循环。但是,这仍然会使页面无响应!

因此,我认为您可以通过使用 setTimeout 调用 UpdatePage 方法来解决该问题。这应该会破坏递归并使页面保持响应。请参阅此 jsFiddle 示例

尝试改成这样:

// build an ajax request; omitted for brevity
$.ajax( {
    .
    . <snip>
    .
    success:  function(data, textStatus, oHTTP ) {
        setTimeout( function() {
            UpdatePage(data, BoxCarIds);
        }, 0);
    }
});

The recursive part here isn't important to the functionality. It's just a consequence of the ajax calls. You could make the ajax calls synchronous and change getNextBoxCar to a loop. However, that will still leave the page unresponsive!

So, I think that you can fix the issue by using a setTimeout to call the UpdatePage method. This should break the recursion and leave the page responsive. See this jsFiddle example.

Try changing to this:

// build an ajax request; omitted for brevity
$.ajax( {
    .
    . <snip>
    .
    success:  function(data, textStatus, oHTTP ) {
        setTimeout( function() {
            UpdatePage(data, BoxCarIds);
        }, 0);
    }
});
緦唸λ蓇 2024-09-15 23:02:06

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

UpdatePagegetNextBoxCar 中删除参数 BoxCarIds。那么你的代码应该可以正常工作。

下面是一个例子:

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

You have BoxCarIds as a global variable, but you are also passing it in as a parameter to UpdatePage and getNextBoxCar. So, when you are inside UpdatePage or getNextBoxCar, you are manipulating the local version of BoxCarIds, not the global one!

Remove the parameter BoxCarIds from UpdatePage and getNextBoxCar. Then your code should work fine.

Below is an example:

var x = 3;

function Eat(x)
    {
        x = 5;
    }

alert(x); //alerts 3
Eat(x);
alert(x); //alerts 3

But if you remove the parameter from Eat, you get:

var x = 3;

function Eat()
    {
        x = 5;
    }

alert(x); //alerts 3
Eat(x);
alert(x); //alerts 5
久而酒知 2024-09-15 23:02:06

我没有看到“编辑”按钮,因此我必须用“答案”来回应建议。无法格式化代码以使其在注释中可读。

上面问题问的时候我就傻眼了。抱歉。实际程序中的BoxCarIds不是全局的。程序是这样的:

 function getBoxCarIds(){
     .  
     .
     .


     var BoxCarIds = data;   // data is returned by webservice
     $('body').triggerHandler('NextBoxCar', BoxCarIds);   // kick things off


 }

BoxCarIds数组的长度实际上是递减的。当“货运列车”相当短时,程序运行良好。只有当火车很长(例如140节车厢)时才会遇到错误。

I don't see an Edit button, so I will have to respond to the suggestions with an Answer. No way to format code to make it readable in the Comment.

I goofed when asking the question above. Apologies. BoxCarIds in the actual program isn't global. The program is like this:

 function getBoxCarIds(){
     .  
     .
     .


     var BoxCarIds = data;   // data is returned by webservice
     $('body').triggerHandler('NextBoxCar', BoxCarIds);   // kick things off


 }

The length of the BoxCarIds array is actually diminishing. When the "freight train" is fairly short, the program runs fine. It's only encountering the error when the train is a long one (e.g. 140 cars).

无声情话 2024-09-15 23:02:06

“太多递归”错误发生在 FF 3.6.6 中 jquery 1.4.2 的第 1936 行:

  // 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 } 

The 'too much recursion' error is happening in FF 3.6.6 at line 1936 in jquery 1.4.2:

  // 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 } 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文