【问题标题】:How to start setInterval loop immediately? [duplicate]如何立即启动 setInterval 循环? [复制]
【发布时间】:2012-05-20 18:11:02
【问题描述】:

简单的setInterval

setInterval(function() {
      // Do something every 9 seconds
}, 9000);

第一个动作将在 9 秒后发生 (t=9s)。如何强制循环立即执行第一个动作(t=0)?

我认为这是由于setInterval 的机制导致Delay - Action - Delay - Action ... 循环;而不是 Action - Delay - Action - Delay ... 循环。

编辑:我的函数确实是一个循环

setInterval(function(){
$('.test').each(function(idx){
    var duration = 1000;
    $(this).delay(duration*idx);
    Some stuff here
});
}, 4000);

【问题讨论】:

  • 发生 JavaScript 的人讨厌 DRY 主体。

标签: javascript jquery setinterval


【解决方案1】:

保持简单。您可以使用命名函数而不是匿名函数;调用它并为它设置一个间隔。

function doSomething() {
    console.log("tick");
}
doSomething();
setInterval(doSomething, 9000);

如有必要,创建一个范围:

(function() {
    function doSomething() {
        console.log("tick");
    }
    doSomething();
    setInterval(doSomething, 9000);
})();

最后,以下工作不会创建或影响x

setInterval(function x() {
    console.log("tick");
    return x;
}(), 9000);

【讨论】:

  • 这个答案的第一部分将逐渐变慢,因为每个循环都会生成一个新的setInterval。这可以通过将window.setInterval 替换为setTimeout 来解决。
  • 我想知道第二个示例如何使用 lambda 函数?
【解决方案2】:

setInterval() 是一个非常丑陋的函数。我使用这个经过净化的版本,它会立即调用函数,并且在函数参数之前需要以秒为单位的时间,因此使用内联函数定义调用它实际上看起来很明智。

function startInterval(seconds, callback) {
  callback();
  return setInterval(callback, seconds * 1000);
}

【讨论】:

  • 如果回调调用 clearInterval(),在第一次调用时,它总是无法清除此实现的间隔。可行的是:const id = setInterval(...); setTimeout(callback); return id; 这可确保在第一次调用回调时没有未定义 intervalId
【解决方案3】:

使用命名函数并调用它并将其分配给区间。

var myFnc = function() {
    // Do something every 9 seconds
};
setInterval(myFnc, 9000);
myFnc();

另一种选择是改用 setTimeout。

var myFnc = function() {
    // Do something every 9 seconds
    setTimeout(myFnc, 9000);
};
myFnc();

【讨论】:

  • 这不是一个命名函数。这是一个分配给变量的匿名函数。 variable 有一个名称,而函数没有(这对你正在做的事情很好,除了一些调试器将无法在调用堆栈中显示一个有用的名称等 [其他人会这样做,最新的 Chrome 开发工具和 Firebug 非常聪明])。
【解决方案4】:

有时我会使用这种模式...

(function me() {
    // Do something every 9 seconds

    setTimeout(me, 9000);
})();

这不完全一样,因为它会等到 do something 被执行,然后再等待大约 9 秒才能再次调用它。但是,这通常很有用,因此事件队列上的事件不会不必要地堆叠(但有些代码不太可能需要 9 秒才能运行 :)

请注意,在较旧的 IE 中,me 将泄漏到外部范围。

【讨论】:

  • “请注意,在较旧的 IE 中,me 会泄漏到外部范围。” 在不同的时间,使用相同的代码创建了两个不同的函数。 第一次 你的代码运行,它就是其中之一;随后的所有时间都是另一个。奇怪但真实。
  • 我希望这可以在所有浏览器上无缝运行。简直太干净了。哪些版本的 IE 出现故障?
  • @thekingoftruth 它应该可以无缝地工作,它只会在 IE 中泄漏me 标识符。根据记忆,
  • @alex 我可以忍受。 :) 我想知道(var me = function(){... 是否也能正常工作。编辑:啊,我知道它不会。
  • @thekingoftruth var <name> = <something>undefined,而<name> = <something><name>(实际上等于<something>。所以你可以这样做var me; (me = function() { … })()
猜你喜欢
  • 1970-01-01
  • 2020-09-18
  • 2015-04-26
  • 2020-05-09
  • 1970-01-01
  • 2020-10-19
  • 2015-10-29
  • 2016-09-19
  • 1970-01-01
相关资源
最近更新 更多