Снижение частоты опроса событий Javascript

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

6 ответов


var resizeTimeout;

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

});

это вызовет setTimeout() функция ~500мс после того как человек заканчивал изменять размер.

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


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


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


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

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

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


Регистрация подчеркивания debounce функции

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

пример:

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

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

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
    //...
}

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