Answers:
第一次直接直接调用该函数最简单:
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();
这样可以确保两次调用之间至少有间隔delay
。如果需要的话,它也使取消循环变得更加容易- setTimeout
达到循环终止条件时,您不会调用。
更好的是,您可以将它们全部包装在立即调用的函数表达式中,该表达式创建函数,然后如上所述再次调用自身,并自动启动循环:
(function foo() {
...
setTimeout(foo, delay);
})();
定义功能并一次性开始循环。
setTimeout
?
setInterval
事件负载可以彼此立即到达而没有任何延迟。
setTimeout
方法,如何停止该功能?
我不确定我是否正确理解了您,但是您可以轻松地执行以下操作:
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
显然有许多方法可以做到这一点,但这是我能想到的最简洁的方法。
arguments.callee
在ES5严格模式下不可用
由于相同的问题,我偶然发现了这个问题,但是如果您需要表现得完全一样,setInterval()
但唯一的区别是该函数在开始时立即被调用,那么所有答案都无济于事。
这是我对这个问题的解决方案:
function setIntervalImmediately(func, interval) {
func();
return setInterval(func, interval);
}
该解决方案的优势:
setInterval
可以容易地通过替代被适配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
,那么你也可以替换原来的setInterval
。因此,在现有代码之前添加以下代码无需更改代码:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
尽管如此,上面列出的所有优点仍适用于此,但无需替代。
setTimeout
方案,因为它返回一个setInterval
对象。为了避免调用可能稍后在代码中并因此在当前时间未定义的函数,我将第一个函数调用包装在这样的setTimeout
函数中:setTimeout(function(){ func();},0);
然后在当前处理周期之后调用第一个函数,该处理周期也立即为,但是更多错误证明。
如果需要,这里有一个包装好的包装物:
(function() {
var originalSetInterval = window.setInterval;
window.setInterval = function(fn, delay, runImmediately) {
if(runImmediately) fn();
return originalSetInterval(fn, delay);
};
})();
将setInterval的第三个参数设置为true,它将在调用setInterval后立即首次运行:
setInterval(function() { console.log("hello world"); }, 5000, true);
或省略第三个参数,它将保留其原始行为:
setInterval(function() { console.log("hello world"); }, 5000);
一些浏览器支持setInterval的其他参数,该包装器没有考虑这些参数。我认为这些很少使用,但是如果您确实需要它们,请记住这一点。
对于某人,需要将外部this
内部带入箭头功能。
(function f() {
this.emit("...");
setTimeout(f.bind(this), 1000);
}).bind(this)();
如果以上产生的垃圾困扰您,则可以改为关闭。
(that => {
(function f() {
that.emit("...");
setTimeout(f, 1000);
})();
})(this);
或者,也许可以考虑使用的@autobind
装饰取决于你的代码。
我建议按以下顺序调用函数
var _timer = setInterval(foo, delay, params);
foo(params)
_timer
如果您希望clearInterval(_timer)
在特定条件下,也可以将传递给foo
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
对于新手来说,这是一个简单的版本,不会一团糟。它只是声明函数,调用它,然后开始间隔。而已。
//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(完整披露,这是我的)。
这里的许多示例都不包含参数处理,也没有更改默认行为 setInterval
在任何大型项目中都是有害的。从文档:
这个图案
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
等同于
firstInterval(callback, 1000, p1, p2);
// 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 hello(status ) {
console.log('world', ++status.count);
return status;
}
setInterval(hello, 5 * 1000, hello({ count: 0 }));
您可以在函数中设置一个很小的初始延迟时间(例如100)并将其设置为所需的延迟时间:
var delay = 100;
function foo() {
console.log("Change initial delay-time to what you want.");
delay = 12000;
setTimeout(foo, delay);
}
立即调用函数存在问题,因为即使将setTimeout / setInterval直接设置为0,标准setTimeout / setInterval的最小超时也只有几毫秒左右。这是由浏览器特定的工作引起的。
零延迟的代码示例可在Chrome,Safari,Opera中使用
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
您可以在这里找到更多信息
在第一次手动调用之后,您可以使用函数创建一个间隔。
function
一次电话,然后进行setInterval()