第一次不延迟执行setInterval函数

有一种方法来configurationjavascript的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(); 

这保证了通话之间至less有一段时间间隔。 如果需要,它也可以更容易地取消循环 – 当达到循环终止条件时,不要调用setTimeout

更好的是,你可以将它们全部包装在一个立即调用的函数expression式中 ,该expression式创build函数,然后如上所述再次调用自身,并自动启动循环:

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

它定义了function,并一次性启动循环。

我不知道我是否正确理解你,但你可以轻松地做这样的事情:

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

显然有很多方法可以做到这一点,但这是我能想到的最简洁的方式。

如果你需要的话,这是一个很好的包装:

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

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

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

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

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

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

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

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

…然后像这样使用它:

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

由于同样的问题,我偶然发现了这个问题,但是如果你需要像setInterval()一样的行为,但是唯一的区别就是函数在开始时立即被调用,没有一个答案有帮助。

这是我解决这个问题的方法:

 function setIntervalImmediately(func, interval) { func(); return setInterval(func, interval); } 

这个解决scheme的优点是:

  • 使用setInterval现有代码很容易通过replace来调整
  • 在严格的模式下工作
  • 它适用于现有的命名函数和闭包
  • 您仍然可以使用返回值并稍后将其传递给clearInterval()

例:

 // create 1 second interval with immediate execution var myInterval = setIntervalImmediately( _ => { console.log('hello'); }, 1000); // clear interval after 4.5 seconds setTimeout( _ => { clearInterval(myInterval); }, 4500); 

要厚脸皮,如果你确实需要使用setInterval那么你也可以replace原来的setInterval 。 因此,在现有代码之前添加此代码时不需要更改代码:

 var setIntervalOrig = setInterval; setInterval = function(func, interval) { func(); return setIntervalOrig(func, interval); } 

尽pipe如此,上面列出的所有优点都适用,但是不需要replace。

如果您将传递给setInterval的代码提取到函数中,则可以在调用setInterval之后立即直接调用该函数。 这实现了相同的效果。

 // YCombinator function anonymous(fnc) { return function() { fnc.apply(fnc, arguments); return fnc; } } // Invoking the first time: setInterval(anonymous(function() { console.log("bar"); })(), 4000); // Not invoking the first time: setInterval(anonymous(function() { console.log("foo"); }), 4000); // Or simple: setInterval(function() { console.log("baz"); }, 4000); 

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

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

使用:

 function poll(f, i){ var cancel = false; function again(){ f(); cancel || setTimeout(again, i); } again(); return function(){ cancel = true; } } poll(task, 1000); 

通过UI效果,将anim组合成poll以进一步减less处理开销:

 function anim(f){ var waf = window.requestAnimationFrame; //browser support? return waf ? function(){ waf(f) } : f; } poll(anim(taskUI), 1000); 

我会build议按以下顺序调用函数

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

你也可以将_timer传递给foo,如果你想在一定条件下clearInterval(_timer)

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

即时asynchronous调用你的函数有一个问题,因为标准的setTimeout / setInterval有一个最小的几毫秒超时,即使你直接把它设置为0.它是由浏览器的具体工作引起的。

在Chrome,Safari,Opera中有一个REAL零延迟代码的例子

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

你可以在这里find更多的信息

在第一次手动呼叫之后,您可以使用您的function创build一个时间间隔。

其实最快的就是这样做

 interval = setInterval(myFunction(),45000) 

这会调用我的function,然后会每45秒做一次与之不同的做法

 interval = setInterval(myfunction, 45000) 

这不会叫它,但只是安排它