2

I wan't to execute a function a specific time (end goal is to synchronize media playback on multiple computers). However I'm seeing a behavior I can't explain. I'm looking for an explanation and a way to circumvent this.

A related problem is How to create an accurate timer in javascript? however that is a bit different. The problem there is to execute multiple times with a set time difference between each execution. Something like "do this every 5 seconds". I'm interested in "do this at 12:05:00", that is to execute once but as close as the correct time as possible. Then the above drift adjusting algorithm can't be used.

Let's start with a test program that takes the current time, cut of the time to seconds and then tries to execute a function 5 seconds (or rather a bit less) in the future:

<script type="text/javascript">
function boom() {
  let timestamp = new Date().getTime();
  console.log(" BOOOOOM!!!     " + timestamp);
}

function runFunction() {
  let currentDate = new Date().getTime();
  let nextDate = Math.floor(currentDate / 1000);
  nextDate += 5;
  nextDate *= 1000;
  let diff = nextDate - currentDate;
  setTimeout(boom, diff);
  console.log("Current time: " + currentDate);
  console.log("Next time:    " + nextDate);
}

runFunction(); 
</script>

My output is

ontime.html:16 Current time: 1550851837630
ontime.html:17 Next time:    1550851842000
ontime.html:4  BOOOOOM!!!    1550851842591

Looks pretty good. I miss the target by 591 ms, that's huge, but if it's the same all the time (and it seems to be so) I can just take that into my calculations:

<script type="text/javascript">
function boom() {
  let timestamp = new Date().getTime();
  console.log(" BOOOOOM!!!     " + timestamp);
}

function runFunction() {
  let currentDate = new Date().getTime();
  let nextDate = Math.floor(currentDate / 1000);
  nextDate += 5;
  nextDate *= 1000;
  let diff = nextDate - currentDate;

  diff -= 591;

  setTimeout(boom, diff);
  console.log("Current time: " + currentDate);
  console.log("Next time:    " + nextDate);
}

runFunction(); 
</script>

My output is

ontime.html:16 Current time: 1550852490754
ontime.html:17 Next time:    1550852495000
ontime.html:4  BOOOOOM!!!    1550852494591

591 ms wrong again! How is this possible?

iveqy
  • 19,951
  • 1
  • 15
  • 20
  • Does that happen every time? Maybe this is just a coincident... – Jonas Wilms Feb 22 '19 at 16:28
  • Timers in JavaScript are buckets, and you can't get millisecond resolution with them. See https://stackoverflow.com/questions/29971898/how-to-create-an-accurate-timer-in-javascript – msanford Feb 22 '19 at 16:31
  • On my browser I'm seeing deltas of 3-5ms (without the 591ms adjustment), which is in line with typical performance for `setTimeout` – nvioli Feb 22 '19 at 16:31

0 Answers0