Cancel timout / timer if function called again --- debounce function

Viewed 861

I want to create a function that starts a timeout, but if the function is called again, before the timer ends, cancel the original call and start the timer again.

I thought I could do:

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

...but that doesn't work, for every time I run setTimer(), it doesn't cancel the original call.

Can anyone point me in the right direction?

3 Answers

setTimeout returns an id you can use to clear that timeout with clearTimeout(). So you can clear the existing timeout at the beginning of your function.

For example if you keep clicking it will keep restarting -- if you don't click it finishes in 2 seconds:

let timerID;

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

What you want to do is cancel the existing timeout and start it over? You can do this by using cleartimeout

let timeoutFunctionVar = null;

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

setTimeoutFunction()

So every time setTimeoutFunction() gets called, the previous timeout gets reset

I figured this question gets asked frequently, especially for searches triggered by key events, but I couldn't find any.

The basic idea is that you keep the timeout id stateful, so you can clear it on subsequent invocations to the TO setter:

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);
}
Related