Javascript Опрос сервера. Это вызовет переполнение стека? - PullRequest
3 голосов
/ 20 июля 2009

Я не слишком знаком со спецификой каждой реализации javascript в каждом браузере. Однако я знаю, что при использовании setTimeout переданный метод вызывается в отдельном потоке. Так будет ли использование метода setTimeout рекурсивно внутри метода вызывать бесконечный рост его стека до тех пор, пока он не вызовет переполнение стека? Или он создаст отдельный стек вызовов и уничтожит текущий кадр, если он не в фокусе? Вот код, который мне интересен.

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

window.setTimeout(pollServer, 0);

Я хочу опрашивать сервер каждую секунду или около того, но не хочу тратить циклы ЦП на «цикл блокировки» - также я не хочу устанавливать ограничение по времени, в течение которого пользователь может получить доступ к странице либо до того, как браузер умирает.

EDIT

Используя firebug, я установил несколько точек останова и, просмотрев панель «Script -> Stack», увидел, что стек вызовов буквально просто «pollServer», и он не увеличивается при каждом вызове. Это хорошо - однако, другие реализации JS действуют по-другому?

Ответы [ 4 ]

2 голосов
/ 20 июля 2009

Я не уверен, что это приведет к переполнению стека, но я предлагаю вам использовать 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;
      }
    }
  }
});
1 голос
/ 21 июля 2009

setTimeout выполняется позже в будущем в цикле накачки событий. Функции, переданные в setTimeout, не являются продолжениями.

Если вы остановитесь и подумаете об этом, какая полезная цель или доказательство в том, что стек вызовов используется функцией тайм-аута.

  • Если бы они были разделены, какой стек будет передаваться из установщика в функцию тайм-аута?
  • Учитывая, что установщик может сделать несколько возвратов и вытолкнуть несколько кадров - что будет передано?
  • Блокирует ли функция тайм-аута оригинальный поток?
  • Выполняется ли оператор после функции setTimeout после истечения времени ожидания?

Как только вы ответите на эти вопросы, станет ясно, что ответом будет НЕТ .

0 голосов
/ 05 июля 2010

взгляните на плагин jQuery "SmartUpdater".

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

Доступны следующие функции:

  • stop () - остановить обновление.
  • restart () - начать обновление после паузы с восстановлением интервала времени до minTimeout.
  • continue () - начать обновление после паузы без сброса временного интервала.
  • атрибут состояния - показывает текущее состояние (выполняется | останавливается | не определено)
  • обновляется, только если новые данные отличаются от старых.
  • умножает интервал времени каждый раз, когда данные не изменяются.
  • обрабатывать сбои ajax , останавливаясь для запроса данных после "maxFailedRequests".
0 голосов
/ 21 июля 2009

setTimeout не увеличивает callstack, потому что он немедленно возвращается. Что касается того, будет ли ваш код работать бесконечно в любом браузере, я не уверен, но это кажется вероятным.

...