0

I have a bit of node.js code as such:

var start = Date.now();

setTimeout(function() {
    console.log(Date.now() - start);
    for (var i = 0; i < 100000; i++) {
    }
}, 1000);

setTimeout(function() {
    console.log(Date.now() - start);
}, 2000);

Something strange happens when I run it on my machine. The times I get are something between 970 and 980, and something between 1970 and 1980. Why am I getting times that are earlier than the timeout times?

swarajd
  • 977
  • 1
  • 10
  • 18
  • 2
    In which browser? Safari returns numbers like 1002 and 2001, similar in Chrome and Firefox. – RobG Sep 02 '14 at 00:40
  • First of all you should remove that `for` loop – using constructs like this in JS is never a good idea. There is no equivalent of a `sleep` function in JS, and trying to create a similar effect using such long-running loops is utter nonsense that will in almost all cases lead to unpredictable or unreliable results. – CBroe Sep 02 '14 at 00:44
  • I get 1002 and 2002 respectively. – Derek 朕會功夫 Sep 02 '14 at 00:49
  • This is just example code, and I am actually running this on my linux machine, not running it in any browser. I have that loop in there simply to simulate an event which takes time. – swarajd Sep 02 '14 at 00:58
  • The Date object isn't intended to be particularly accurate, some implementations only have a 15ms precision. Consider using [*performance.now*](http://www.w3.org/TR/hr-time/#dom-performance-now) ([*MDN link*](https://developer.mozilla.org/en-US/docs/Web/API/Performance.now())) if supported. – RobG Sep 02 '14 at 02:04
  • 1
    I ran your code on node.js on Windows and got two numbers I would expect: `1015` and `2001` which are pretty much when the two timers are set to fire. Right now, I'd say your numbers are not reproducible. – jfriend00 Sep 02 '14 at 05:57

2 Answers2

2

I believe you're experiencing these issues because of the Date precision. It can vary across platforms and browsers.

Here's a more detailed read on the accuracy of Date.

There are more high precision timers available on some platforms, but you will often have to do some mix and match (detect what's available and regress accordingly).

Cristi Mihai
  • 2,505
  • 1
  • 19
  • 20
1

From the node.js setTimeOut documentation:

It is important to note that your callback will probably not be called in exactly delay milliseconds - Node.js makes no guarantees about the exact timing of when the callback will fire, nor of the ordering things will fire in. The callback will be called as close as possible to the time specified.

However, there is a nanotimer to play with:
https://www.npmjs.org/package/nanotimer

Some related questions:

However, I do think +/- 30ms early is a bit much (compared to most browsers I've played with, they are usually no more than 10ms later (as long as the cpu isn't maxed out, that is)).

Community
  • 1
  • 1
GitaarLAB
  • 14,536
  • 11
  • 60
  • 80