Change setInterval value dynamically

后端 未结 3 1350
心在旅途
心在旅途 2021-02-04 11:01

I want to change interval value of setInterval dynamically. I\'m struggling due to presence of a loop in setInterval callback function. I have seen too many questions on stackov

相关标签:
3条回答
  • 2021-02-04 11:37

    The trick is to not use setInterval, and to use setTimeout in a loop instead.

    setInterval reads the timing value you give it once, schedules based on this timing, and forgets about it. The only thing you can do is clearInterval(myInterval) if you've assigned your interval to a variable like myInterval.

    setTimeout is much the same, except we can use it to manually loop on the same function. Manually looping allows us to change the timing of setTimeout after each timeout.

    Here's a quick example. Moving the slider to the left makes the ticking faster, and to the right, slower.

    DEMO

    var timing = 250,
        i = 0,
        output = document.getElementById('output');
    
    function loop() {
      i++;
      output.innerHTML = i;
      window.setTimeout(loop, timing);
    }
    
    document.querySelector('input[type="range"]').addEventListener('change', function (e) {
      timing = parseInt(this.value);
    });
    
    loop();
    <input type="range" min="100" max="500" value="250" />
    <div id="output"></div>

    As a side note: Using this pattern is almost always a better option than using setInterval. setInterval runs the chance that your function execution could take longer than the duration of the interval. This never happens with a looping setTimeout if you call setTimeout last in the function.

    Documentation:

    • WindowTimers.setInterval
    • WindowTimers.setTimeout
    0 讨论(0)
  • 2021-02-04 11:42

    Here's another easy way to dynamically update interval.

    var intv_sec = 1500; // Initial interval in milliseconds
    var speed = 1.5; // Multiplier
    
    function chk_fn(){
      // Your code here
      console.log(intv_sec);
      
      
      // Reset and update interval
      clearInterval(chkh);
      intv_sec = intv_sec*speed;
      chkh = setInterval(chk_fn, intv_sec);
    }
    
    var chkh = setInterval(chk_fn, intv_sec);

    0 讨论(0)
  • 2021-02-04 11:44

    This is a version without setInterval i always use:

    function timer()
    {
        var timer = {
            running: false,
            iv: 5000,
            timeout: false,
            cb : function(){},
            start : function(cb,iv,sd){
                var elm = this;
                clearInterval(this.timeout);
                this.running = true;
                if(cb) this.cb = cb;
                if(iv) this.iv = iv;
                if(sd) elm.execute(elm);
                this.timeout = setTimeout(function(){elm.execute(elm)}, this.iv);
            },
            execute : function(e){
                if(!e.running) return false;
                e.cb();
                e.start();
            },
            stop : function(){
                this.running = false;
            },
            set_interval : function(iv){
                clearInterval(this.timeout);
                this.start(false, iv);
            }
        };
        return timer;
    }
    

    Usage:

    var timer_1 = new timer();
    timer_1.start(function(){
        //magic here
    }, 2000, false);
    
    var timer_2 = new timer();
    timer_2.start(function(){
        //more magic here
    }, 3000, true);
    
    //change the interval
    timer_2.set_interval(4000);
    
    //stop the timer
    timer_1.stop();
    

    The last parameter of the start function is a boolean if the function needs to be run at 0.

    You can also find the script here: https://github.com/Atticweb/smart-interval

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