有一种方法可以配置javascript的setInterval方法来立即执行该方法,然后与计时器一起执行


当前回答

最简单的方法是自己第一次直接调用函数:

foo();
setInterval(foo, delay);

然而,有很好的理由避免setInterval——特别是在某些情况下,整个setInterval事件负载可以在彼此之后立即到达,没有任何延迟。另一个原因是,如果你想停止循环,你必须显式调用clearInterval,这意味着你必须记住从最初的setInterval调用返回的句柄。

因此,另一种方法是让foo在后续调用中使用setTimeout来触发自身:

function foo() {
   // do stuff
   // ...

   // and schedule a repeat
   setTimeout(foo, delay);
}

// start the cycle
foo();

这保证了调用之间至少有一个延迟间隔。如果需要的话,它还使取消循环变得更容易——当达到循环终止条件时,您不需要调用setTimeout。

更好的是,你可以把这一切都包装在一个立即调用的函数表达式中,它创建了函数,然后像上面一样再次调用自己,并自动启动循环:

(function foo() {
    ...
    setTimeout(foo, delay);
})();

它定义了函数,并开始了整个循环。

其他回答

对于那些使用React的人,下面是我解决这个问题的方法:

const intervalRef = useRef(0);

useEffect(() => {
    if (condition is true){
        if (intervalRef.current === 0) {
            callMyFunction();
        }
        const interval = setInterval(() => {
            callMyFunction();
        }, 5_000);
        intervalRef.current = interval;
    } else {
        clearInterval(intervalRef.current);
    }
}, [deps]);

其实最快的就是去做

interval = setInterval(myFunction(),45000)

它会调用myfunction,然后每45秒再做一次,这和之前做的不一样

interval = setInterval(myfunction, 45000)

它不会调用它,但只安排它

如果你需要,这里有一个包装来美化它:

(function() {
    var originalSetInterval = window.setInterval;

    window.setInterval = function(fn, delay, runImmediately) {
        if(runImmediately) fn();
        return originalSetInterval(fn, delay);
    };
})();

将setInterval的第三个参数设置为true,它将在调用setInterval后立即运行:

setInterval(function() { console.log("hello world"); }, 5000, true);

或者省略第三个参数,它将保持原来的行为:

setInterval(function() { console.log("hello world"); }, 5000);

一些浏览器支持setInterval的附加参数,但这个包装器没有考虑到这些参数;我认为这些很少使用,但如果你确实需要它们,请记住这一点。

你可以在函数中设置一个非常小的初始延迟时间(例如100),并将其设置为你想要的延迟时间:

Var延迟= 100; 函数foo() { console.log("改变初始延迟时间为你想要的。"); 延迟= 12000; setTimeout (foo,延迟); }

在ES2017中,最好完全避免使用setInterval。

下面的解决方案具有更清晰的执行流程,可以防止函数需要比预期时间更长的时间才能完成的问题,并允许异步操作。

const timeout = (delayMs) => new Promise((res, _rej) => setTimeout(res, delayMs));

const DELAY = 1_000;

(async () => {
  while (true) {
    let start_time = Date.now();

    // insert code here...

    let end_time = Date.now();
    await timeout(DELAY - (end_time - start_time));
  }
})();