第一次不延迟执行setInterval函数

IT技术 javascript setinterval
2021-02-07 11:52:26

有没有办法将setIntervaljavascript方法配置为立即执行方法然后用定时器执行

6个回答

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

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方法,如何停止该功能
2021-03-15 11:52:26
你为什么喜欢setTimeout
2021-03-18 11:52:26
@GauravBhor,与停止 setInterval 的方式相同,记住 setTimeout 返回的 id,然后调用 clearTimeout(id) ... 或者设置条件以在函数中的下一个间隔运行或不运行。
2021-03-23 11:52:26
@DaveMunger 不,因为它不是真正的递归——它只是“伪递归”。“递归”调用不会发生,直到浏览器返回到事件循环,此时调用堆栈已完全展开。
2021-03-31 11:52:26
@Sangdol 因为它确保计时器事件在未处理时不会“堆叠”。在某些情况下,一整套setInterval事件可以在没有任何延迟的情况下立即到达。
2021-04-04 11:52:26

我不确定我是否正确理解您,但您可以轻松地执行以下操作:

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

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

这是一个很酷的答案,因为它是一个立即执行并返回自身的命名函数。正是我要找的。
2021-03-12 11:52:26
绝对是一个很酷的解决方案,但可能会给将来阅读的人们带来困惑。
2021-03-18 11:52:26
这种 Javascript 代码会让大多数来自其他语言的新 JS 程序员感到困惑。如果你的公司没有很多 JS 人员并且你想要工作安全,那么写一堆这样的东西。
2021-03-27 11:52:26
你不需要给它一个名字“你好”。您可以改为返回 arguments.callee 并与匿名函数相同
2021-04-06 11:52:26
@JochenJungarguments.callee在 ES5 严格模式下不可用
2021-04-10 11:52:26

由于同样的问题,我偶然发现了这个问题,但是如果您需要表现得完全一样,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);然后在当前处理周期之后调用第一个函数,这也是立即调用,但是更多的错误证明。
2021-03-16 11:52:26
您可以使用...args参数并...args在每个函数中再次使用它...
2021-03-17 11:52:26

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

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

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

instantGratification( function() {
    console.log( 'invoked' );
}, 3000);
我认为您应该返回 setInterval 返回的内容。这是因为否则你不能使用 clearInterval。
2021-04-05 11:52:26

这是一个包装器,可以在您需要时对其进行漂亮的处理:

(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 的附加参数,这个包装器没有考虑到这些参数我认为这些很少使用,但如果您确实需要它们,请记住这一点。

覆盖本机浏览器功能很糟糕,因为它会在规范更改时破坏其他共存的代码。其实setInterval目前参数比较多:developer.mozilla.org/en-US/docs/Web/API/WindowTimers/...
2021-04-04 11:52:26