第一次没有延迟地执行setInterval函数

时间:2011-07-13 20:44:43

标签: javascript setinterval

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

14 个答案:

答案 0 :(得分:440)

第一次直接自己调用函数是最简单的:

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

定义函数并一次性开始循环。

答案 1 :(得分:178)

我不确定我是否正确理解你,但你可以很容易地做到这样的事情:

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

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

答案 2 :(得分:10)

由于同样的问题,我偶然发现了这个问题,但是如果您需要完全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);
}

尽管如此,上面列出的所有优点都适用于此,但不需要替换。

答案 3 :(得分:6)

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

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

...然后像这样使用它:

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

答案 4 :(得分:6)

如果你需要它,这里有一个很好的包装:

(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 additional arguments,而这个包装器没有考虑到这一点;我认为这些很少使用,但如果你确实需要它们,请记住这一点。

答案 5 :(得分:2)

对于某人来说,需要将外部this像箭一样放在里面。

(function f() {
    this.emit("...");
    setTimeout(f.bind(this), 1000);
}).bind(this)();

如果上述产生的垃圾困扰您,则可以改为关闭。

(that => {
    (function f() {
        that.emit("...");
        setTimeout(f, 1000);
    })();
})(this);

或者根据您的代码考虑使用the @autobind decorator

答案 6 :(得分:1)

// 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);

答案 7 :(得分:1)

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

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

如果您想在某个条件下_timer,也可以将 clearInterval(_timer) 传递给foo

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

答案 8 :(得分:0)

要解决此问题,我会在页面加载后第一次运行该函数。

function foo(){ ... }

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

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

答案 9 :(得分:0)

这是一个方便的npm包,名为firstInterval(完全披露,它是我的)。

这里的许多示例都不包含参数处理,并且在任何大型项目中更改setInterval的默认行为都是邪恶的。来自文档:

此模式

setInterval(callback, 1000, p1, p2);
callback(p1, p2);

相同
firstInterval(callback, 1000, p1, p2);

如果您在浏览器中读书并且不想要依赖,那么the code.

可以轻松剪切并粘贴

答案 10 :(得分:0)

您可以在函数中设置一个很小的初始延迟时间(例如100)并将其设置为所需的延迟时间:

var delay = 100;

function foo() {
  console.log("Change initial delay-time to what you want.");
  delay = 12000;
  setTimeout(foo, delay);
}

答案 11 :(得分:-1)

对于新手来说,这是一个简单的版本,而不会一团糟。它只是声明函数,调用它,然后开始间隔。就是这样。

//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 );

答案 12 :(得分:-2)

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

具有REAL零延迟的代码示例,适用于Chrome,Safari,Opera

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

您可以找到更多信息here

在第一次手动调用后,您可以使用您的功能创建一个间隔。

答案 13 :(得分:-9)

实际上最快的是

interval = setInterval(myFunction(),45000)

这将调用myfunction,然后每45秒执行一次,这与执行

不同
interval = setInterval(myfunction, 45000)

不会调用它,但只安排它