Javascript民意调查服务器。这会导致堆栈溢出吗?

时间:2009-07-20 18:51:12

标签: javascript stack-overflow callstack ajax-polling

我不太熟悉每个浏览器上每个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的任何其他实现都有不同的行为吗?

4 个答案:

答案 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。

如果你停下来想一想,有什么用途或证据表明调用堆栈是由超时函数共享的。

  • 如果共享了什么堆栈将从setter共享到超时功能?
  • 鉴于setter可以做一些返回并弹出一些帧 - 会传递什么?
  • 超时功能是否会阻止原始线程?
  • 执行超时后执行setTimeout函数后的语句吗?

一旦你回答了这些问题,答案显然是 NO

答案 2 :(得分:0)

setTimeout不会增加callstack,因为它会立即返回。至于你的代码是否会在任何浏览器中无限期运行,我不确定,但似乎很可能。

答案 3 :(得分:0)

看看jQuery“SmartUpdater”插件。

http://plugins.jquery.com/project/smartupdater

以下功能可用:

  • 停止() - 停止更新。
  • restart() - 暂停后开始更新,并将时间间隔重置为minTimeout。
  • 继续() - 暂停后开始更新而不重置时间间隔。
  • 状态属性 - 显示当前状态(正在运行|停止|未定义)
  • 仅在新数据与旧数据不同时更新。
  • 每次数据未更改时,
  • 倍增时间间隔
  • 通过在“maxFailedRequests”之后停止请求数据来处理ajax失败