3

I'm trying to provide a pause and resume functionality to a loop with recursive calls. I'm using "setTimeout" and "clearTimeout" functions for this...

When a user clicks the button "pause", the timer is set to infinite time (maximum possible). When the user clicks the button "resume", the timeout is supposed to be cleared with "clearTimeout" call. But the timeout is never cleared. What is my mistake?

Thank you in advance..

JFIDDLE DEMO

HTML:

<button id="loop_controler">pause</button>

JS:

var array = [1,2,3,4,5,6,7];
var pause = false;
var timer;

function execute(array,i){
    var pauseTime = 0;
    if (pause){
        pauseTime = 2147483647;  //max value for timeout     
    }
    timer = setTimeout(function(){        //set timer
           setTimeout(function () {       
               alert(array[i]);           //this timeout gives a constant delay
               if (array.length > i)      //(just to give enough time to users to click button)
                   execute(array,i+1);
           }, 1000);
    }, pauseTime);
    console.log('set ' + timer);
}

$('document').ready(function(){

    $('#loop_controler').click(function(){
        if ($(this).text() == 'pause'){
          pause = true;
          $(this).text('resume');
        } else {
          clearTimeout(timer);           //clear timer
          console.log('clear ' + timer);
          pause = false;
          $(this).text('pause');
        }
    });

    execute(array,0);
});
5
  • Why don't you clear the timeout when the user clicks Pause, instead of setting the timeout to infinity? And then start it again when the user clicks resume. Commented Nov 2, 2014 at 6:44
  • The main problem is that after you clear the timeout, you're not restarting it with a normal timeout. Commented Nov 2, 2014 at 6:45
  • You need i to be a global variable, so you can restart the timer at the current position in the array. Commented Nov 2, 2014 at 6:46
  • See this similar answer I gave earlier tonight: stackoverflow.com/questions/26695911/… Commented Nov 2, 2014 at 6:47
  • I was misunderstanding the clearTimeout function. I thought the callback would be executed immediately after we clear the timeout... Thank you a lot for your help.. Commented Nov 2, 2014 at 7:41

2 Answers 2

7

Back in 2012 I wrote a snippet of code for delta timing in JavaScript, which uses setTimeout and has start and stop functions: https://gist.github.com/aaditmshah/2056987

See the demo:

var button = document.querySelector("button");
var div = document.querySelector("div");

var running = false;

var number = 1;

var timer = new DeltaTimer(function () {
  div.innerHTML = number++;
}, 1000);

button.addEventListener("click", function () {
  if (running) {
    timer.stop();
    button.innerHTML = "Start";
    running = false;
  } else {
    timer.start();
    button.innerHTML = "Stop";
    running = true;
  }
});

function DeltaTimer(render, interval) {
    var timeout;
    var lastTime;

    this.start = start;
    this.stop = stop;

    function start() {
        timeout = setTimeout(loop, 0);
        lastTime = Date.now();
        return lastTime;
    }

    function stop() {
        clearTimeout(timeout);
        return lastTime;
    }

    function loop() {
        var thisTime = Date.now();
        var deltaTime = thisTime - lastTime;
        var delay = Math.max(interval - deltaTime, 0);
        timeout = setTimeout(loop, delay);
        lastTime = thisTime + delay;
        render(thisTime);
    }
}
<button>Start</button>
<div></div>

Hope that helps.

Sign up to request clarification or add additional context in comments.

Comments

2

I was misunderstanding the clearTimeout function. I thought the callback (calback in setTimeout(...)) would be executed immediately after clearTimeout is called. But the callback is not executed after clearTimeout is called...

The working JS code is,

var array = [1,2,3,4,5,6,7];
var timer;
var i=0;

function execute(){
     timer = setTimeout(function () {
               alert(array[i]);
               i++;
               if (array.length > i){
                   execute();
               }
           }, 1000);
}

$('document').ready(function(){

    $('#loop_controler').click(function(){
        if ($(this).text() == 'pause'){
          clearTimeout(timer);
          $(this).text('resume');
        } else {
          execute();
          $(this).text('pause');
        }
    });

    execute(array,0);
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.