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


当前回答

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

其他回答

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

function foo(){ ... }

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

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

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

函数的即时异步调用存在一个问题,因为标准的setTimeout/setInterval即使直接将其设置为0,也具有大约几毫秒的最小超时。这是由浏览器特定的工作引起的。

一个具有REAL零延迟的代码示例,可在Chrome, Safari, Opera中工作

function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}

你可以在这里找到更多信息

在第一次手动调用之后,您可以用函数创建一个间隔。

我建议按以下顺序调用这些函数

var _timer = setInterval(foo, delay, params);
foo(params)

你也可以把_timer传递给foo,如果你想在特定的条件下清除interval (_timer)

var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);

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