Понизьте частоту опроса событий Javascript - PullRequest
7 голосов
/ 07 декабря 2010

Как снизить частоту опроса событий JavaScript?Я обеспокоен событиями onResize и onScroll .Эти события могут запускаться десятки раз в секунду, когда кто-то изменяет размер своего браузера или прокручивает его соответственно.Я бы хотел, чтобы эти события происходили только один раз каждые 500 мс, поэтому мне не нужно тратить часы на оптимизацию моих обработчиков событий и следить за тем, чтобы они не пропускали память.

Ответы [ 6 ]

9 голосов
/ 07 декабря 2010
var resizeTimeout;

window.onresize = function() {
    if (resizeTimeout) {
        clearTimeout(resizeTimeout);
    }
    resizeTimeout = setTimeout(function() {
        // Do it!
    }, 500);

});

Это вызовет функцию setTimeout() через 500 мс после того, как человек завершит изменение размера.

Версия onscroll очень похожа:)

5 голосов
/ 07 декабря 2010

Вы не можете реально контролировать частоту возникновения события, вы можете сделать что-то вроде запоминания времени первого срабатывания события, а затем при каждом последующем проверять, не превышает ли оно 500 мс с первого - если да, вы продолжаетес обработчиком событий, в противном случае вы просто выходите из обработчика событий

1 голос
/ 07 декабря 2010

Вы не можете предотвратить запуск этих событий. Они всегда делают. Что вы хотите сделать, это немедленно прекратить прослушивание, а затем обработать событие, чтобы избежать повторения. Затем весь обработчик устанавливается снова после setTimeout. Больше никакой рекурсии не происходит, если кто-то не изменяет размеры окна. Я использую 5000 мс здесь, так как это легче увидеть в консоли. Вы не должны видеть больше одного спама в консоли FF каждые 5 секунд, даже если вы изменяете размер как spaz.

(function staggerListen(){
  window.onresize = function(){
    window.onresize = false;
    console.log('spam');
    setTimeout(staggerListen,5000);
  };
})()

Использование логики, чтобы решить, делать ли что-либо каждый раз при срабатывании обработчика, все еще технически запускает обработчик и оператор if + lookup. Это может стать тяжелым.

1 голос
/ 07 декабря 2010

В начале вашего обработчика проверьте, прошло ли 500 мс с момента последнего, и просто верните, если нет.

0 голосов
/ 18 мая 2017

Раньше я делал так, как на принятом ответе, но проблема в том, что он срабатывает только после указанного времени ожидания.Я хотел решение, которое обрабатывает изменение размера сразу, в первый раз.Вот что я в итоге сделал.

var _resize_is_busy = false;
var _resize_scheduled = false;
var _resize_precision = 100;

// This register for window resize events. No need to change anything.
$(window).resize(function () {

    if (!_resize_is_busy) {

        // call the scheduler who will do the work and set a timer to
        // check of other resizes occured within a certain period of time

        _resize_scheduler();
    }
    else {

        // the resizer is busy, i.e. a resize have been handled a little
        // time ago and then the scheduler is waiting some time before 
        // handling any other resize. This flag tells the scheduler that
        // a resize event have been receive while he was sleeping.

        _resize_scheduled = true;
    }
});

// This is the scheduler. No need to change anything.
var _resize_scheduler = function () {

    _resize_is_busy = true;
    _resize_scheduled = false;

    setTimeout(function () {

        _resize_is_busy = false;

        if (_resize_scheduled) 
            _handle_resize();

    }, _resize_precision);

    _handle_resize();
}

var _handle_resize = function () {

    console.log('DOING ACTUAL RESIZE');

    // do the work here
    //...
}

Надеюсь, это поможет.

0 голосов
/ 03 декабря 2012

проверка нижнего подчеркивания debounce function

Создает и возвращает новую отклоненную версию переданной функции, которая будет откладывать ее выполнение до истечения миллисекунд ожидания, прошедших с момента последнего запуска.был вызван.Полезно для реализации поведения, которое должно происходить только после того, как ввод прекратил поступать.Например: предварительный просмотр комментария к Markdown, пересчет макета после того, как размер окна перестает быть изменен, и т. Д.

Пример:

window.onscroll = _.debounce(
  function() {
      // do something
  }, 500, false
);
...