Отменить тайм-аут/таймер, если функция вызывается снова, debounce function

Я хочу создать функцию, которая запускает тайм-аут, но если функция вызывается снова, до окончания таймера отмените первоначальный вызов и снова запустите таймер.

Я думал, что смогу сделать:

function setTimer() {
   setTimeout(() => {
      // do something
   }, 3000)
} 

... но это не работает, каждый раз, когда я запускаю setTimer(), исходный вызов не отменяется.

Может кто-то указать мне верное направление?


person Smokey Dawson    schedule 17.09.2018    source источник
comment
Основываясь на том, что вы описали, то, что вы ищете, называется debounce.   -  person CRice    schedule 18.09.2018


Ответы (3)


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

Например, если вы продолжаете нажимать, он будет перезапускаться - если вы не нажимаете, он завершается через 2 секунды:

let timerID;

function setTimer() {
  console.log("starting/restarting timer")
  clearTimeout(timerID)
  timerID = setTimeout(() => {
    console.log("finished")
  }, 2000)
}
<p onclick="setTimer()">click to start</p>

person Mark    schedule 17.09.2018
comment
Спасибо, это именно то, что я искал! - person Smokey Dawson; 18.09.2018

Что вы хотите сделать, это отменить существующий тайм-аут и начать его заново? Вы можете сделать это с помощью cleartimeout.

let timeoutFunctionVar = null;

const setTimeoutFunction = () => {
    clearTimeout(timeoutFunctionVar)
    timeoutFunctionVar = setTimeout(() => {
        // do something
    }, 3000)
};

setTimeoutFunction()

Таким образом, каждый раз, когда вызывается setTimeoutFunction(), предыдущий тайм-аут сбрасывается.

person Pieter-Jan Beeckman    schedule 18.09.2018

Я понял, что этот вопрос часто задают, особенно для поиска, вызванного ключевыми событиями, но я не смог найти ни одного.

Основная идея заключается в том, что вы сохраняете идентификатор времени ожидания. с сохранением состояния, поэтому вы можете очистить его при последующих вызовах установщика TO:

const MS_IN_SEC = 1000;

let old_timeout;

function TO_setter(searchString) {
    if (old_timeout)
        window.clearTimeout(old_timeout);

    old_timeout = window.setTimeout(search, 2 * MS_IN_SEC, searchString);
}

function search(s) {
    console.log('search for: %s', s);
}
person Rafael    schedule 18.09.2018
comment
Я тоже так предполагал, но тоже ничего не нашел. - person Smokey Dawson; 18.09.2018