我不太熟悉每个浏览器上每个javascript实现的细节。但我确实知道使用setTimeout,传入的方法会在一个单独的线程上调用。那么在方法内部递归使用setTimeout会导致其堆栈无限增长,直到它导致堆栈溢出?或者它会创建一个单独的callstack并在它失焦后销毁当前帧?这是我想知道的代码。
function pollServer()
{
$.getJSON("poll.php", {}, function(data){
window.setTimeout(pollServer, 1000);
});
}
window.setTimeout(pollServer, 0);
我想每隔一秒左右轮询一次服务器,但不想浪费带有'阻塞循环'的CPU周期 - 我也不想设置一个时间限制用户可以访问页面的时间长度浏览器死了。
修改
使用firebug,我设置了几个断点,通过查看“Script - > Stack”面板,看到调用堆栈实际上只是“pollServer”,并且每次调用都不会增长。这很好 - 但是,JS的任何其他实现都有不同的行为吗?
答案 0 :(得分:2)
我不确定它是否会产生堆栈溢出,但如果句点不变,我建议您使用setInterval
。
这是prototype实现其PeriodicalExecuter
。
// Taken from Prototype (www.prototypejs.org)
var PeriodicalExecuter = Class.create({
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;
this.registerCallback();
},
registerCallback: function() {
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
execute: function() {
this.callback(this);
},
stop: function() {
if (!this.timer) return;
clearInterval(this.timer);
this.timer = null;
},
onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
this.execute();
} finally {
this.currentlyExecuting = false;
}
}
}
});
答案 1 :(得分:1)
setTimeout将在以后的事件泵循环中执行。传递给setTimeout的函数不是continuation。
如果你停下来想一想,有什么用途或证据表明调用堆栈是由超时函数共享的。
一旦你回答了这些问题,答案显然是 NO 。
答案 2 :(得分:0)
setTimeout不会增加callstack,因为它会立即返回。至于你的代码是否会在任何浏览器中无限期运行,我不确定,但似乎很可能。
答案 3 :(得分:0)
看看jQuery“SmartUpdater”插件。
http://plugins.jquery.com/project/smartupdater
以下功能可用: