开发者

How can I avoid overloading the JavaScript CallStack?

The javascript below accomplishes the following (this is for a node.js COMET application):

  1. Request is made to the server and held until the server has something to return.
  2. Once the request returns the data is processed and another request is immediately made within the callback function of the success event.
  3. If a timeout occurs (the server had nothing to return within the time frame) another request is made within the callback function of the error event.

My concern (which I believe is valid) is that the requests are continually added to the callstack, much like a recursive function that never ends. After a while, it results in the browser eventually crashing and becoming unresponsive (at least I think this is the cause).

开发者_如何转开发

How can I accomplish the same thing and avoid this problem?

function GetData(){
    $.ajax({
        url: "admin.html",
        type: "POST",
        dataType: "json",
        contentType: 'text/json',
        data: JSON.stringify({
            cmd: "getData"
        }),
        timeout: (60 * 1000),
        success: function(data, textStatus, jqXHR){
            UpdateScreen(data);
            GetData();
        },
        error: function(jqXHR, textStatus, errorThrown){
            if(textStatus == "timeout"){
                GetData();
            }
        }
    });
}


No, I'm pretty sure you are OK. The ajax event is asynchronous, so the GetData function will finish and the browser will wait for events, before it calls GetData again from the success handler.

Think of it as the GetData function just defining what to do, not actually doing it. Then it finishes executing (and clears the stack) and browser does those actions.


function GetData(limit){
    limit = limit || 0;
    $.ajax({
        url: "admin.html",
        type: "POST",
        dataType: "json",
        contentType: 'text/json',
        data: JSON.stringify({
            cmd: "getData"
        }),
        timeout: (60 * 1000),
        success: function(data, textStatus, jqXHR){
            UpdateScreen(data);
            GetData();
        },
        error: function(jqXHR, textStatus, errorThrown){
            if(textStatus === "timeout" && limit < 20){
                GetData(++limit); 
            } else {
                //throw "epic fail"
                setTimeout(GetData, 0);
            }
        }
    });
}

Just add a little timeout limit counter. if it gets too big either give up and throw an error or break the call stack by calling setTimeout which is asynchronous.


I'm wondering if your UpdateScreen(data) method is the problem. Is that a recursive function as well? People suggesting that you simply timeout the method doesn't actually fix the problem, it simply aborts the process. I would try logging something like console.log("get data success") and console.log("get data error") in your success and error callbacks respectively. If your log page is full of one message, you know where the GetData() method is continually called. It could be always timing out.

On a side note, you should change your if statement for an error to something like

   if(jqxhr.responseText == "timeout"){
      getData();
   }

see here for explanation why: jQuery Ajax error handling, show custom exception messages

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜