jquery / backbone.js - задержка вызова функции - PullRequest
4 голосов
/ 20 июля 2011

У меня есть элемент #search, который при возникновении события keyup должен запускать функцию. Эта функция должна срабатывать только в том случае, если keyup не произошло в установленное время (например, 500 миллисекунд). Это предотвратит обновление результатов поиска каждой нажатой буквой. Проблема в том, что в backbone.js мои события хранятся в хэше, а тот, который применим, выглядит следующим образом:

'keyup #search' : 'setSearch'

, которая вызывает функцию setSearch(), когда происходит событие keyup. Я не совсем понимаю, как справиться с этим на данный момент. Я пробовал разные вещи, но ничто не может поддерживать таймер после завершения функции.

У меня есть что-то вроде этого:

setSearch: function(event) {
            var timer = window.setTimeout( function() {
                // run function here
                alert('fired');
            }, 500);
    },

вместо alert('fired') у меня будет собственная функция. Я могу понять, почему этот код не работает (таймер установлен для каждого keyup события, которое происходит. Но у меня все еще нет четкого представления о том, что еще можно попробовать.

Ответы [ 4 ]

19 голосов
/ 23 августа 2011

То, что вы ищете, на самом деле - функция, предоставленная вам из underscore.js (требование Backbone)вызываться один раз каждые 500 мс.Скорее всего, вам придется настроить время под свои нужды.

Подробнее: http://documentcloud.github.com/underscore/#throttle

3 голосов
/ 20 июля 2011

Вам нужна переменная экземпляра в вашем представлении, которая хранит идентификатор таймера, затем вы можете остановить его и перезапустить при необходимости:

setSearch: function(event) {
    var self = this;
    if(self.timer)
        clearTimeout(self.timer);
    self.timer = setTimeout(function() {
        alert('fired');
        self.timer = null;
    }, 500);
}

Итак, если таймер уже работает, вы вызываете clearTimeout, чтобы остановить его, запустить новый таймер и сохранить идентификатор таймера в self.timer (AKA this.timer). Вы также захотите сбросить сохраненный идентификатор таймера в функции обратного вызова таймера, иначе ваш setSearch ничего не сделает после того, как таймер сработал один раз. И вся бизнес self состоит в том, чтобы просто захватить this для использования в функции обратного вызова таймера.

1 голос
/ 09 сентября 2014

Предотвращение обновления результатов поиска на каждом keyup - это именно та ситуация, с которой должна справиться функция Underscore _.debounce(function, wait). Документация подчеркивания для _.debounce () гласит:

Создает и возвращает новую отклоненную версию переданного function, которая будет откладывать его выполнение до истечения wait миллисекунд с момента последнего вызова. Полезно для реализации поведения, которое должно происходить только после того, как ввод прекратил поступать.

Ваш реорганизованный код будет выглядеть так же просто, как:

setSearch: function(event) {
    _.debounce(doSomething, 300);
},
0 голосов
/ 20 июля 2011

Поскольку вы хотите, чтобы события вашего обработчика событий могли поддерживать, независимо от того, имеет ли событие recentlyFired, вы, вероятно, хотите заключить свой обработчик в замыкание и поддерживать этот статус. Состояние должно быть изменено на true при возникновении события и сброшено на false после задержки 500 мс.

setSearch: function( ) {
    var firedRecently = false;
    return function(event) {
        if (firedRecently) {
            // it has fired recently. Do you want to do something here?
        } else {
            // not fired recently
            firedRecently = true;
            // run your function here
            alert('fired');
            var resetStatus = window.setTimeout( function () {
                firedRecently = false;
            }, 500);
        }
    }
}( );
...