我在JavaScript中进行了一个非常简单的Comet式长轮询 下面的代码似乎工作,但它是递归调用自己和吃资源吗?我怎么说?
编辑:根据Dogberts建议编辑代码
$(document).ready(function () {
function doSuccess(data) {
$('#res').html(data.time + "<br/>" + data.data);
startAjax();
}
function doError(jqXHR, textStatus, errorThrown) {
$('#res').html(textStatus + ":" + errorThrown);
startAjax();
}
function startAjax() {
$.ajax({
url: 'http://127.0.0.1:12345/',
dataType: 'jsonp',
success: doSuccess, //Edit: updated as per Dogbert's suggestion
error: doError
});
}
startAjax();
});
我对它运行http://home.orange.nl/jsrosman/并且它看起来没问题(我只是在专业上偏执)startAjax调用(well callsBack)doSuccess调用startAjax
答案 0 :(得分:3)
不,这不应该吃任何额外的资源。您在旧请求完成后正确调用该方法。
旁注,这个
success: function (data) {
doSuccess(data);
},
error: function (jqXHR, textStatus, errorThrown) {
doError(jqXHR, textStatus, errorThrown);
}
可以写成
success: doSuccess,
error: doError
答案 1 :(得分:1)
对我来说看起来不错:每个新请求都是在旧请求过期后发出的
答案 2 :(得分:1)
该代码中没有递归,startAjax
在调用后立即退出。虽然可以最大限度地减少内存使用,但你可以在不调用内存的情况下重新定义函数,但最终无论如何都会使用旧函数,因为无法引用它们。 @ Dogbert的答案显示了如何避免重新定义函数,但这并不重要,因为无论如何都没有形成永久闭包。
Closure形成定义为:当一个外部函数被调用时,它定义了一个内部函数,并且那些(那些)内部函数在外部函数退出后是可用的。
现在,如果您要在同步模式下执行ajax,那么startAjax
将永远不会退出,并且会间接调用更多startAjax
,并且最终会达到最大调用堆栈大小。更不用说您的UI将被锁定100%的时间。
例如,在Google Chrome中运行此功能,您将获得:
RangeError: Maximum call stack size exceeded
function success(){
startAjax();
}
function error(){
startAjax();
}
function startAjax(){
synchronousAjax( success, error );
}
function synchronousAjax( success, error){
Math.random() < 0.5 ? success() : error();
}
startAjax();
答案 3 :(得分:0)
最初是对你的问题发表评论,但它比我预期的要长一点......
就内存泄漏而言,这对我来说很好 - 你没有在任何地方分配任何变量,所以垃圾收集器没问题。
然而,考虑到这种方法的递归特性,你最终可能会遇到堆栈溢出 - 它永远不会“触底”来展开堆栈。您是否可以使用setTimeout
定期启动流程?