How to create an accurate timer in javascript?

前端 未结 10 2300
一个人的身影
一个人的身影 2020-11-22 01:32

I need to create a simple but accurate timer.

This is my code:

var seconds = 0;
setInterval(function() {
timer.innerHTML = seconds++;
}, 1000);
         


        
10条回答
  •  南方客
    南方客 (楼主)
    2020-11-22 02:30

    Inspired by Bergi's answer I created the following complete non drifting timer. What I wanted was a way to set a timer, stop it, and do this simply.

    var perfectTimer = {                                                              // Set of functions designed to create nearly perfect timers that do not drift
        timers: {},                                                                     // An object of timers by ID
      nextID: 0,                                                                      // Next available timer reference ID
      set: (callback, interval) => {                                                  // Set a timer
        var expected = Date.now() + interval;                                         // Expected currect time when timeout fires
        var ID = perfectTimer.nextID++;                                               // Create reference to timer
        function step() {                                                             // Adjusts the timeout to account for any drift since last timeout
          callback();                                                                 // Call the callback
          var dt = Date.now() - expected;                                             // The drift (ms) (positive for overshooting) comparing the expected time to the current time
          expected += interval;                                                       // Set the next expected currect time when timeout fires
          perfectTimer.timers[ID] = setTimeout(step, Math.max(0, interval - dt));     // Take into account drift
        }
        perfectTimer.timers[ID] = setTimeout(step, interval);                         // Return reference to timer
        return ID;
      },
      clear: (ID) => {                                                                // Clear & delete a timer by ID reference
        if (perfectTimer.timers[ID] != undefined) {                                   // Preventing errors when trying to clear a timer that no longer exists
          console.log('clear timer:', ID);
          console.log('timers before:', perfectTimer.timers);
          clearTimeout(perfectTimer.timers[ID]);                                      // Clear timer
          delete perfectTimer.timers[ID];                                             // Delete timer reference
          console.log('timers after:', perfectTimer.timers);
        }
        }       
    }
    
    
    
    
    // Below are some tests
    var timerOne = perfectTimer.set(() => {
        console.log(new Date().toString(), Date.now(), 'timerOne', timerOne);
    }, 1000);
    console.log(timerOne);
    setTimeout(() => {
        perfectTimer.clear(timerOne);
    }, 5000)
    
    var timerTwo = perfectTimer.set(() => {
        console.log(new Date().toString(), Date.now(), 'timerTwo', timerTwo);
    }, 1000);
    console.log(timerTwo);
    
    setTimeout(() => {
        perfectTimer.clear(timerTwo);
    }, 8000)

提交回复
热议问题