Execute the setInterval function without delay the first time

后端 未结 14 2152
故里飘歌
故里飘歌 2020-11-22 16:17

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

相关标签:
14条回答
  • 2020-11-22 16:40

    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 setInterval events 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 clearInterval which means you have to remember the handle returned from the original setInterval call.

    So an alternative method is to have foo trigger itself for subsequent calls using setTimeout instead:

    function foo() {
       // do stuff
       // ...
    
       // and schedule a repeat
       setTimeout(foo, delay);
    }
    
    // start the cycle
    foo();
    

    This guarantees that there is at least an interval of delay between calls. It also makes it easier to cancel the loop if required - you just don't call setTimeout when your loop termination condition is reached.

    Better yet, you can wrap that all up in an immediately invoked function expression which 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.

    0 讨论(0)
  • 2020-11-22 16:41

    I will suggest calling the functions in the following sequence

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

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

    var _timer = setInterval(function() { foo(_timer, params) }, delay);
    foo(_timer, params);
    
    0 讨论(0)
  • 2020-11-22 16:44

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

    Here is my solution to this problem:

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

    The advantage of this solution:

    • existing code using setInterval can 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

    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 setInterval then you could also replace the original setInterval. Hence, no change of code required when adding this before your existing code:

    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.

    0 讨论(0)
  • 2020-11-22 16:45

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

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

    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.

    0 讨论(0)
  • 2020-11-22 16:45

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

    Ok this is so complex, so, let me put it more simple:

    function hello(status ) {    
      console.log('world', ++status.count);
      
      return status;
    }
    
    setInterval(hello, 5 * 1000, hello({ count: 0 }));

    0 讨论(0)
  • 2020-11-22 16:47

    You can set a very small initial delay-time (e.g. 100) and set it to your desired delay-time within the function:

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

    0 讨论(0)
提交回复
热议问题