最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Cancel timouttimer if function called again --- debounce function - Stack Overflow

programmeradmin3浏览0评论

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?

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?

Share Improve this question edited Sep 18, 2018 at 0:25 Rafael 7,74613 gold badges33 silver badges48 bronze badges asked Sep 17, 2018 at 23:51 Smokey DawsonSmokey Dawson 9,24022 gold badges85 silver badges162 bronze badges 1
  • 2 Based on what you've described, what you're looking for is called "debounce". – CRice Commented Sep 17, 2018 at 23:56
Add a ment  | 

3 Answers 3

Reset to default 6

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);
}
发布评论

评论列表(0)

  1. 暂无评论