解決setInterval計時器不准的問題


在js中如果打算使用setInterval進行倒數,計時等功能,往往是不准確的,因為setInterval的回調函數並不是到時后立即執行,而是等系統計算資源空閑下來后才會執行.而下一次觸發時間則是在setInterval回調函數執行完畢之后才開始計時,所以如果setInterval內執行的計算過於耗時,或者有其他耗時任務在執行,setInterval的計時會越來越不准,延遲很厲害.

下面的代碼可以說明這個問題

var startTime = new Date().getTime();
var count = 0;
//耗時任務
setInterval(function(){
	var i = 0;
	while(i++ < 100000000);
}, 0);
setInterval(function(){
	count++;
	console.log(new Date().getTime() - (startTime + count * 1000));
}, 1000);

代碼里輸出了setInterval觸發時間和應該正確觸發時間的延遲毫秒數

176
340
495
652
807
961
1114
1268
1425
1579
1734
1888
2048
2201
2357
2521
2679
2834
2996 
......

可以看到延遲是越來越嚴重的.

為了在js里可以使用相對准確的計時功能,我們可以

var startTime = new Date().getTime();
var count = 0;
setInterval(function(){
	var i = 0;
	while(i++ < 100000000);
}, 0);
function fixed() {
	count++;
	var offset = new Date().getTime() - (startTime + count * 1000);
	var nextTime = 1000 - offset;
	if (nextTime < 0) nextTime = 0;
	setTimeout(fixed, nextTime);
	
	console.log(new Date().getTime() - (startTime + count * 1000));
}
setTimeout(fixed, 1000);

代碼里,通過1000(也就是周期時間)減去當前時間和准確時間的差距,來算出下次觸發的時間,從而修正了當前觸發的延遲.

下面是輸出

186
200
230
271
158
899
900
899
900
899
899
899
902
899
418
202
232
266
145
174
192
214
242
268
149
179
214 
......

可以看到雖然觸發時間並非絕對准確,但由於每次觸發都進行及時修正,所以並沒有造成誤差積累.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM