Amc_rtty
Amc_rtty

Reputation: 3813

Javascript Stopwatch not working

I have a stopwatch that must call setInterval and increase a variable every millisecond, so that I get the ElapsedTime when I call Stop(). This I will use to measure the time necessary for a request, but for the sake of simplicity i just added a sleep function

   function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}


var Stopwatch = 
{
    ElapsedTime: 0,
    CounterId :0, 

    IncrementElapsedTime:function(){
            this.ElapsedTime++;
            console.log("incremented to: " + this.ElapsedTime);    
    },

    Start: function(){
        this.CounterId = setInterval(this.IncrementElapsedTime(), 1);
    },


    Stop: function(){
        clearInterval(this.CounterId);
    }
}

Stopwatch.Start();

sleep(500);

Stopwatch.Stop();
console.log("final result: " + Stopwatch.ElapsedTime);

I expect that since I waited 500 milliseconds, the ElapsedTime after calling Stop is exactly that, 500. But the ElapsedTime just shows 1 instead of 500. What do I do wrong? Thanks

--

Explanation - after reading the comments i understood that my intention is simlpy not clear - all I want is to get an elapsed time, in milliseconds, between the interval start and clear. Can someone point me in the right direction is this code is not the best way to do this, thanks

Upvotes: 1

Views: 95

Answers (2)

James Jithin
James Jithin

Reputation: 10565

There are two points to look into. Inside the start, you cannot refer this in setInterval. This needs a global reference as it executes detached from the object from where setInterval is triggered. Second point is the script executor goes busy with your sleep() and forgets to execute what you wanted to. Moreover, setInterval should not be used for precised applications. The following code counts only till 2646 on my browser, even though I asked to stop timer after 10000ms:

   var Stopwatch = 
    {
        ElapsedTime: 0,
        CounterId :0,
        IncrementElapsedTime:function(){
                this.ElapsedTime++;
                console.log("incremented to: " + this.ElapsedTime);    
        },

        Start: function(){
            this.CounterId = setInterval(function(){Stopwatch.IncrementElapsedTime();}, 1);
        },


        Stop: function(){
            clearInterval(this.CounterId);
        }
    }

    Stopwatch.Start();
    setTimeout(function() {
        Stopwatch.Stop();
        console.log("final result: " + Stopwatch.ElapsedTime);
    }, 10000);

Upvotes: 1

Spencer Wieczorek
Spencer Wieczorek

Reputation: 21575

This is due to JavaScript being only sequentially single threaded and not multi-threaded. This means that while the busy loop sleep() is running, there cannot be any calls from setInterval, which leads to it being only called once before .Stop() is called.

As long as the elapsed time isn't being stopped by busy loops or blocking execution (like prompts), you will get a correct value from .Stop().

Upvotes: 1

Related Questions