Execute the setInterval function without delay the first time
有一种方法可以配置javascript的
第一次直接直接调用函数是最简单的:
1 2 | foo(); setInterval(foo, delay); |
但是,有充分的理由避免使用
因此,另一种方法是让
1 2 3 4 5 6 7 8 9 10 | function foo() { // do stuff // ... // and schedule a repeat setTimeout(foo, delay); } // start the cycle foo(); |
这样可以确保两次调用之间至少间隔
更好的是,您可以将它们全部包装在立即调用的函数表达式中,该表达式创建函数,然后如上再次调用自身,并自动启动循环:
1 2 3 4 | (function foo() { ... setTimeout(foo, delay); })(); |
定义功能并一次性开始循环。
我不确定我是否理解正确,但是您可以轻松地执行以下操作:
1 2 3 4 | setInterval(function hello() { console.log('world'); return hello; }(), 5000); |
显然有许多方法可以做到这一点,但这是我能想到的最简洁的方法。
由于相同的问题,我偶然发现了这个问题,但是如果您需要表现得完全像
这是我对这个问题的解决方案:
1 2 3 4 | function setIntervalImmediately(func, interval) { func(); return setInterval(func, interval); } |
该解决方案的优势:
-
使用
setInterval 的现有代码可以很容易地通过替换来适应 - 在严格模式下工作
- 它与现有的命名函数和闭包一起工作
-
您仍然可以使用返回值,然后将其传递给
clearInterval()
例:
1 2 3 4 5 6 7 8 9 | // create 1 second interval with immediate execution var myInterval = setIntervalImmediately( _ => { console.log('hello'); }, 1000); // clear interval after 4.5 seconds setTimeout( _ => { clearInterval(myInterval); }, 4500); |
出于厚颜无耻,如果您确实需要使用
1 2 3 4 5 6 | var setIntervalOrig = setInterval; setInterval = function(func, interval) { func(); return setIntervalOrig(func, interval); } |
尽管如此,上面列出的所有优点仍适用于此,但无需替代。
您可以将
1 2 3 4 | function instantGratification( fn, delay ) { fn(); setInterval( fn, delay ); } |
...然后像这样使用它:
1 2 3 | instantGratification( function() { console.log( 'invoked' ); }, 3000); |
如果需要,这里有一个包装好的包装物:
1 2 3 4 5 6 7 8 | (function() { var originalSetInterval = window.setInterval; window.setInterval = function(fn, delay, runImmediately) { if(runImmediately) fn(); return originalSetInterval(fn, delay); }; })(); |
将setInterval的第三个参数设置为true,它将在调用setInterval后立即首次运行:
1 | setInterval(function() { console.log("hello world"); }, 5000, true); |
或省略第三个参数,它将保留其原始行为:
1 | setInterval(function() { console.log("hello world"); }, 5000); |
一些浏览器支持setInterval的其他参数,该包装器没有考虑这些参数。我认为这些很少使用,但是如果您确实需要它们,请记住这一点。
对于某人,需要将外部
1 2 3 4 | (function f() { this.emit("..."); setTimeout(f.bind(this), 1000); }).bind(this)(); |
如果以上产生的垃圾困扰您,则可以改为关闭。
1 2 3 4 5 6 | (that => { (function f() { that.emit("..."); setTimeout(f, 1000); })(); })(this); |
或者也许考虑使用
我建议按以下顺序调用函数
1 2 | var _timer = setInterval(foo, delay, params); foo(params) |
如果要在特定条件下
1 2 | var _timer = setInterval(function() { foo(_timer, params) }, delay); foo(_timer, params); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // 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); |
对于新手来说,这是一个简单的版本,不会一团糟。 它只是声明函数,调用它,然后开始间隔。 而已。
1 2 3 4 5 6 7 8 9 10 | //Declare your function here function My_Function(){ console.log("foo"); } //Call the function first My_Function(); //Set the interval var interval = window.setInterval( My_Function, 500 ); |
有一个方便的npm包,称为firstInterval(完整披露,这是我的)。
这里的许多示例都不包含参数处理,并且在任何大型项目中更改
这个图案
1 2 | setInterval(callback, 1000, p1, p2); callback(p1, p2); |
与...相同
1 | firstInterval(callback, 1000, p1, p2); |
如果您是浏览器的老手,并且不希望依赖,则可以轻松地从代码中剪切和粘贴。
为了解决这个问题,我在页面加载后第一次运行该函数。
1 2 3 4 5 6 7 8 9 10 | function foo(){ ... } window.onload = function() { foo(); }; window.setInterval(function() { foo(); }, 5000); |
立即调用函数存在问题,因为即使直接将setTimeout / setInterval设置为0,标准setTimeout / setInterval的最小超时也只有几毫秒左右。这是由浏览器特定的工作引起的。
真正延迟为零的代码示例可在Chrome,Safari,Opera中使用
1 2 3 4 5 | function setZeroTimeout(callback) { var channel = new MessageChannel(); channel.port1.onmessage = callback; channel.port2.postMessage(''); } |
您可以在这里找到更多信息
在第一次手动调用之后,您可以使用函数创建一个间隔。
实际上最快是
1 | interval = setInterval(myFunction(),45000) |
这将调用myfunction,然后每45秒执行一次agaian操作,这与实际操作不同
1 | interval = setInterval(myfunction, 45000) |
不会调用它,而只安排它