3

我不太熟悉每个浏览器上每个 javascript 实现的细节。但是我知道使用 setTimeout,传入的方法会在单独的线程上调用。那么在方法内部递归使用 setTimeout 会导致其堆栈无限增长,直到导致堆栈溢出?或者它会创建一个单独的调用堆栈并在失去焦点后销毁当前帧?这是我想知道的代码。

function pollServer()
{
    $.getJSON("poll.php", {}, function(data){
        window.setTimeout(pollServer, 1000);
    });
}

window.setTimeout(pollServer, 0);

我想每隔一秒左右轮询一次服务器,但不想通过“阻塞循环”浪费 CPU 周期——我也不想设置用户在浏览器死机之前可以访问页面的时间限制。

编辑

使用萤火虫,我设置了几个断点,通过查看“脚本 - >堆栈”面板看到调用堆栈实际上只是“pollServer”,它不会在每次调用时增长。这很好 - 但是,JS 的任何其他实现是否有不同的行为?

4

4 回答 4

2

我不确定它是否会造成堆栈溢出,但我建议您setInterval在周期不变的情况下使用。

这就是原型如何实现它的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;
      }
    }
  }
});
于 2009-07-20T19:00:45.387 回答
1

setTimeout 在事件泵循环中稍后的某个时间执行。传递给 setTimeout 的函数不是延续。

如果你停下来想一想,调用堆栈被超时函数共享有什么有用的目的或证据。

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

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

于 2009-07-21T02:11:36.667 回答
0

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

于 2009-07-21T02:04:52.667 回答
0

看看 jQuery“SmartUpdater”插件。

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

提供以下功能:

  • stop() - 停止更新。
  • restart() - 暂停后开始更新,将时间间隔重置为 minTimeout。
  • continue() - 在暂停后开始更新而不重置时间间隔。
  • 状态属性- 显示当前状态(运行 | 停止 | 未定义)
  • 仅当新数据与旧数据不同时才更新。
  • 每次数据未更改时乘以时间间隔。
  • 通过在“maxFailedRequests”之后停止请求数据来处理 ajax 失败。
于 2010-07-05T10:44:49.087 回答