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


当前回答

有一个方便的npm包叫做firstInterval(完全披露,它是我的)。

这里的许多示例都不包括参数处理,在任何大型项目中更改setInterval的默认行为都是有害的。从文档中可以看出:

这种模式

setInterval(callback, 1000, p1, p2);
callback(p1, p2);

等于

firstInterval(callback, 1000, p1, p2);

如果您使用的是老式浏览器,并且不想要依赖项,那么可以简单地从代码中剪切和粘贴。

其他回答

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

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

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

如果你可以使用RxJS,有一个叫做timer()的东西:

import { Subscription, timer } from 'rxjs';

const INITIAL_DELAY = 1;
const INTERVAL_DELAY = 10000;
const timerSubscription = timer(INITIAL_DELAY, INTERVAL_DELAY)
  .subscribe(() => {
    this.updateSomething();
  });

// when destroying
timerSubscription.unsubscribe();

你可以将setInterval()包装在提供该行为的函数中:

function instantGratification( fn, delay ) {
    fn();
    setInterval( fn, delay );
}

...然后这样使用它:

instantGratification( function() {
    console.log( 'invoked' );
}, 3000);

对于那些使用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]);

为了解决这个问题,我在页面加载后第一次运行这个函数。

function foo(){ ... }

window.onload = function() {
   foo();
};

window.setInterval(function()
{
    foo(); 
}, 5000);