Will setInterval drift?

JavascriptSetinterval

Javascript Problem Overview


This is a pretty simple question really. If I use setInterval(something, 1000), can I be completely sure that after, say, 31 days it will have triggered "something" exactly 60*60*24*31 times? Or is there any risk for so called drifting?

Javascript Solutions


Solution 1 - Javascript

Short answer: No, you can't be sure. Yes, it can drift.

Long answer: John Resig on the Accuracy of JavaScript Time and How JavaScript Timers Work.

From the second article:

>In order to understand how the timers work internally there's one important concept that needs to be explored: timer delay is not guaranteed. Since all JavaScript in a browser executes on a single thread asynchronous events (such as mouse clicks and timers) are only run when there's been an opening in the execution.

Both articles (and anything on that site) is great reading, so have at it.

Solution 2 - Javascript

Here's a benchmark you can run in Firefox:

var start = +new Date();
var count = 0;
setInterval(function () {
    console.log((new Date() - start) % 1000,
    ++count,
    Math.round((new Date() - start)/1000))
}, 1000);

First value should be as close to 0 or 1000 as possible (any other value shows how "off the spot" the timing of the trigger was.) Second value is number of times the code has been triggered, and third value is how many times the could should have been triggered. You'll note that if you hog down your CPU it can get quite off the spot, but it seems to correct itself. Try to run it for a longer period of time and see how it handles.

Solution 3 - Javascript

(Sorry about my bad english) I had same problem about counting down function, i writed a function countdown() and loop with setInterval but its drifting 1-3 milliseconds per loop. Then i write a function that controls is there any drifting and fixed it.

It controls with real minute and second only. Here it is. Its works fine to me, i hope it will help you too.

$.syncInterval(functionname,interval,controlinterval)

example:

countdown(){ some code };
$.syncInterval(countdown,1000,60);

it says run countdown function every 1000 milliseconds and check it every 60 seconds

here is the code:

$.syncInterval = function (func,interval,control) { 
		var 
		now=new Date();
		realMinute=now.getMinutes(),
		realSecond=now.getSeconds(),
		nowSecond=realSecond,
		nowMinute=realMinute,
		minuteError=0,
		countingVar=1,
		totalDiff=0;

		var loopthat = setInterval(function(){
		
		if (nowSecond==0) {
			nowMinute++;
			nowMinute=nowMinute%60;
		};
		if (countingVar==0){
			
			now=new Date();
			realSecond=now.getSeconds();
			realMinute=now.getMinutes();
			
			totalDiff=((realMinute*60)+(realSecond))-((nowMinute*60)+(nowSecond));
			if(totalDiff>0){
				for (i=1;i<=totalDiff;i++) {
					func();
					nowSecond++;
					countingVar++;
				};
			} else if (totalDiff==0){
				func();
				nowSecond++;
				countingVar++;
			} else if (totalDiff<0) {
				
			};
		} else {
			func();
			nowSecond++;
			countingVar++;
		};
		countingVar=countingVar%control;
		nowSecond=nowSecond%60;
	},interval);
};

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDeniz DoganView Question on Stackoverflow
Solution 1 - JavascriptPaolo BergantinoView Answer on Stackoverflow
Solution 2 - JavascriptBlixtView Answer on Stackoverflow
Solution 3 - JavascripttunabtView Answer on Stackoverflow