重置超时的正确方法是什么?

What is the right way to reset a timeout?

所以我有这样的功能:

function blabla(){
    ...

    setTimeout(() => {
        //do some stuff
    }, 10000) 
}   

现在如果函数被调用但超时尚未完成,我如何重置超时时间(10000)?
如果它确实存在,我试图终止超时:

function blabla(){
    ...

    if(to){
       clearTimeout(to)
    } 

    let to = setTimeout(() => {
        //do some stuff
    }, 10000) 
}  

但我收到错误消息,指出 to 未定义。那么检查超时是否存在的正确方法是什么。有更好的方法吗?

你只需要在if之前声明to,这样当if运行时它就存在(并且没有undefined)。您不必稍后再给它一个实际值。

实际上,您可能希望在函数外部声明它,这样下次调用该函数时它会一直存在。

这是一个可运行的演示。请注意,尽管调用 blablah() 两次,但您只看到一次 "hello",因为对该函数的第二次调用取消了原始超时。

var to;

function blabla() {
  //...

  if (to) {
    clearTimeout(to)
  }

  to = setTimeout(() => {
    //do some stuff
    console.log("hello");
  }, 10000)
}

blabla();
blabla();

为此使用全局变量不是个好主意,因为它不可重用。 最好为该函数编写包装器,因为它是通用模式。此本机代码或为此使用 npm 数据包

Debounce functions are included in many JavaScript libraries. The goal behind each implementation is to reduce overhead by preventing a function from being called several times in succession. Regardless of the library, all debounce functions are built on JavaScript's native setTimeout function.

https://www.npmjs.com/package/debounce:

function debounce(func, wait, immediate) {
    let timeout;
    return function() {
        let context = this,
            args = arguments;
        let later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        let callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

var blabla = debounce(function(){
     console.log(5)
}, 5000);
blabla()
blabla()

不要使用letlet作用域在函数块内部。 如果你第二次调用这个函数,这个函数没有让定义。 使用 var 以便在跨函数调用中可以访问它。