Javascript 第一次不延迟执行setInterval函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6685396/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:48:49  来源:igfitidea点击:

Execute the setInterval function without delay the first time

javascriptsetinterval

提问by Jorge

It's there a way to configure the setIntervalmethod of javascript to execute the method immediately and then executes with the timer

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

回答by Alnitak

It's simplest to just call the function yourself directly the first time:

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

foo();
setInterval(foo, delay);

However there are good reasons to avoid setInterval- in particular in some circumstances a whole load of setIntervalevents can arrive immediately after each other without any delay. Another reason is that if you want to stop the loop you have to explicitly call clearIntervalwhich means you have to remember the handle returned from the original setIntervalcall.

然而,有充分的理由可以避免setInterval- 特别是在某些情况下,一整套setInterval事件可以在没有任何延迟的情况下立即到达。另一个原因是,如果您想停止循环,您必须显式调用clearInterval,这意味着您必须记住从原始setInterval调用返回的句柄。

So an alternative method is to have footrigger itself for subsequent calls using setTimeoutinstead:

因此,另一种方法是foo使用setTimeout代替为后续调用触发自身:

function foo() {
   // do stuff
   // ...

   // and schedule a repeat
   setTimeout(foo, delay);
}

// start the cycle
foo();

This guarantees that there is at leastan interval of delaybetween calls. It also makes it easier to cancel the loop if required - you just don't call setTimeoutwhen your loop termination condition is reached.

这保证了调用之间至少有一个间隔delay。如果需要,它还可以更轻松地取消循环 - 您只是setTimeout在达到循环终止条件时不调用。

Better yet, you can wrap that all up in an immediately invoked function expressionwhich creates the function, which then calls itself again as above, and automatically starts the loop:

更好的是,您可以将所有这些都包装在一个立即调用的函数表达式中,该函数表达式创建该函数,然后如上所述再次调用自身,并自动启动循环:

(function foo() {
    ...
    setTimeout(foo, delay);
})();

which defines the function and starts the cycle all in one go.

它定义了函数并一口气开始循环。

回答by chjj

I'm not sure if I'm understanding you correctly, but you could easily do something like this:

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

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

There's obviously any number of ways of doing this, but that's the most concise way I can think of.

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

回答by Jens Wirth

I stumbled upon this question due to the same problem but none of the answers helps if you need to behave exactlylike setInterval()but with the onlydifference that the function is called immediately at the beginning.

由于同样的问题,我偶然发现了这个问题,但是如果您需要表现得完全一样,setInterval()唯一的区别是在开始时立即调用该函数,这些答案都没有帮助。

Here is my solution to this problem:

这是我对这个问题的解决方案:

function setIntervalImmediately(func, interval) {
  func();
  return setInterval(func, interval);
}

The advantage of this solution:

该解决方案的优点:

  • existing code using setIntervalcan easily be adapted by substitution
  • works in strict mode
  • it works with existing named functions and closures
  • you can still use the return value and pass it to clearInterval()later
  • 使用的现有代码setInterval可以很容易地通过替换进行调整
  • 在严格模式下工作
  • 它适用于现有的命名函数和闭包
  • 您仍然可以使用返回值并将其传递给clearInterval()以后

Example:

例子:

// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
        console.log('hello');
    }, 1000);

// clear interval after 4.5 seconds
setTimeout( _ => {
        clearInterval(myInterval);
    }, 4500);

To be cheeky, if you really need to use setIntervalthen you could also replace the original setInterval. Hence, no change of code required when adding this before your existing code:

厚颜无耻,如果你真的需要使用,setInterval那么你也可以替换原来的setInterval. 因此,在现有代码之前添加此代码时无需更改代码:

var setIntervalOrig = setInterval;

setInterval = function(func, interval) {
    func();
    return setIntervalOrig(func, interval);
}

Still, all advantages as listed above apply here but no substitution is necessary.

尽管如此,上面列出的所有优点在这里都适用,但不需要替代。

回答by user113716

You could wrap setInterval()in a function that provides that behavior:

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

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

...then use it like this:

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

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

回答by Mahn

Here's a wrapper to pretty-fy it if you need it:

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

(function() {
    var originalSetInterval = window.setInterval;

    window.setInterval = function(fn, delay, runImmediately) {
        if(runImmediately) fn();
        return originalSetInterval(fn, delay);
    };
})();

Set the third argument of setInterval to true and it'll run for the first time immediately after calling setInterval:

将 setInterval 的第三个参数设置为 true,它将在调用 setInterval 后立即运行第一次:

setInterval(function() { console.log("hello world"); }, 5000, true);

Or omit the third argument and it will retain its original behaviour:

或者省略第三个参数,它将保留其原始行为:

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

Some browsers support additional argumentsfor setInterval which this wrapper doesn't take into account; I think these are rarely used, but keep that in mind if you do need them.

一些浏览器支持setInterval 的附加参数,这个包装器没有考虑到这些参数;我认为这些很少使用,但如果您确实需要它们,请记住这一点。

回答by Константин Ван

For someone needs to bring the outer thisinside as if it's an arrow function.

因为有人需要把外部this放在里面,就好像它是一个箭头函数。

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

If the above producing garbage bothers you, you can make a closure instead.

如果上面产生的垃圾困扰你,你可以做一个闭包。

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

Or maybe consider using the @autobinddecoratordepending on your code.

或者,也许可以考虑使用@autobind装饰取决于你的代码。

回答by Jayant Varshney

I will suggest calling the functions in the following sequence

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

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

You can also pass the _timerto the foo, if you want to clearInterval(_timer)on a certain condition

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

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

回答by Polyducks

Here's a simple version for novices without all the messing around. It just declares the function, calls it, then starts the interval. That's it.

这是一个适合新手的简单版本,没有任何麻烦。它只是声明函数,调用它,然后开始间隔。就是这样。

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

回答by jimm101

There's a convenient npm package called firstInterval(full disclosure, it's mine).

有一个名为firstInterval的方便的 npm 包(完全公开,这是我的)。

Many of the examples here don't include parameter handling, and changing default behaviors of setIntervalin any large project is evil. From the docs:

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

This pattern

这个图案

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

is identical to

等同于

firstInterval(callback, 1000, p1, p2);

If you're old school in the browser and don't want the dependency, it's an easy cut-and-paste from the code.

如果您是浏览器的老派并且不想要依赖项,那么从代码中可以轻松剪切和粘贴

回答by jimm101

To solve this problem , I run the function a first time after the page has loaded.

为了解决这个问题,我在页面加载后第一次运行该函数。

function foo(){ ... }

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

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