我该如何避免重载JavaScript CallStack?
下面的javascript完成以下(这是一个node.js COMET应用程序):
- 向服务器发出请求,并等待服务器返回一些内容。
- 一旦请求返回,数据被处理并且在成功事件的callback函数内立即发出另一个请求。
- 如果发生超时(服务器在时间范围内没有任何内容可以返回),那么在错误事件的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消息