setInterval計時器不準的問題解決方案

來源:互聯網
上載者:User

在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
......

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.