第一次不延迟执行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)
这不会叫它,但只是安排它