我该如何避免重载JavaScript CallStack?

下面的javascript完成以下(这是一个node.js COMET应用程序):

  1. 向服务器发出请求,并等待服务器返回一些内容。
  2. 一旦请求返回,数据被处理并且在成功事件的callback函数内立即发出另一个请求。
  3. 如果发生超时(服务器在时间范围内没有任何内容可以返回),那么在错误事件的callback函数中会发出另一个请求。

我的担心(我认为是有效的)是请求被不断地添加到调用堆栈,就像一个永无止境的recursion函数。 一段时间后,它导致浏览器最终崩溃,变得没有反应(至less我认为这是原因)。

我怎样才能做到这一点,并避免这个问题?

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

不,我很确定你没事。 ajax事件是asynchronous的,因此GetData函数将完成,浏览器将等待事件,然后再从成功处理程序调用GetData

可以把它看作GetData函数,只是定义要做什么,而不是实际执行。 然后它完成执行(并清除堆栈),浏览器执行这些操作。

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

只需添加一个小超时限制计数器。 如果它变得太大,或者放弃抛出错误或者通过调用asynchronous的setTimeout来打破调用堆栈。

我想知道你的UpdateScreen(数据)方法是否是问题。 这是一个recursion函数吗? 人们build议你简单地超时该方法实际上并不能解决问题,它只是中止这个过程。 我会尝试在成功和错误callback中分别logging像console.log(“获取数据成功”)和console.log(“获取数据错误”)。 如果您的日志页面充满了一条消息,则知道GetData()方法在哪里被连续调用。 它可能总是超时。

在附注中,你应该把你的if语句改成类似的东西

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

请看这里解释为什么: jQuery Ajaxerror handling,显示自定义exception消息