setInterval計(jì)時(shí)器不準(zhǔn)的問(wèn)題解決方法
更新時(shí)間:2014年05月08日 15:45:32 作者:
在js中如果打算使用setInterval進(jìn)行倒數(shù),計(jì)時(shí)等功能,往往是不準(zhǔn)確的,針對(duì)這個(gè)問(wèn)題,本文有個(gè)不錯(cuò)的解決方案
在js中如果打算使用setInterval進(jìn)行倒數(shù),計(jì)時(shí)等功能,往往是不準(zhǔn)確的,因?yàn)閟etInterval的回調(diào)函數(shù)并不是到時(shí)后立即執(zhí)行,而是等系統(tǒng)計(jì)算資源空閑下來(lái)后才會(huì)執(zhí)行.而下一次觸發(fā)時(shí)間則是在setInterval回調(diào)函數(shù)執(zhí)行完畢之后才開(kāi)始計(jì)時(shí),所以如果setInterval內(nèi)執(zhí)行的計(jì)算過(guò)于耗時(shí),或者有其他耗時(shí)任務(wù)在執(zhí)行,setInterval的計(jì)時(shí)會(huì)越來(lái)越不準(zhǔn),延遲很厲害.
下面的代碼可以說(shuō)明這個(gè)問(wèn)題
var startTime = new Date().getTime();
var count = 0;
//耗時(shí)任務(wù)
setInterval(function(){
var i = 0;
while(i++ < 100000000);
}, 0);
setInterval(function(){
count++;
console.log(new Date().getTime() - (startTime + count * 1000));
}, 1000);
代碼里輸出了setInterval觸發(fā)時(shí)間和應(yīng)該正確觸發(fā)時(shí)間的延遲毫秒數(shù)
176
340
495
652
807
961
1114
1268
1425
1579
1734
1888
2048
2201
2357
2521
2679
2834
2996
......
可以看到延遲是越來(lái)越嚴(yán)重的.
為了在js里可以使用相對(duì)準(zhǔn)確的計(jì)時(shí)功能,我們可以
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);
代碼里,通過(guò)1000(也就是周期時(shí)間)減去當(dāng)前時(shí)間和準(zhǔn)確時(shí)間的差距,來(lái)算出下次觸發(fā)的時(shí)間,從而修正了當(dāng)前觸發(fā)的延遲.
下面是輸出
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
......
可以看到雖然觸發(fā)時(shí)間并非絕對(duì)準(zhǔn)確,但由于每次觸發(fā)都進(jìn)行及時(shí)修正,所以并沒(méi)有造成誤差積累.
下面的代碼可以說(shuō)明這個(gè)問(wèn)題
復(fù)制代碼 代碼如下:
var startTime = new Date().getTime();
var count = 0;
//耗時(shí)任務(wù)
setInterval(function(){
var i = 0;
while(i++ < 100000000);
}, 0);
setInterval(function(){
count++;
console.log(new Date().getTime() - (startTime + count * 1000));
}, 1000);
代碼里輸出了setInterval觸發(fā)時(shí)間和應(yīng)該正確觸發(fā)時(shí)間的延遲毫秒數(shù)
復(fù)制代碼 代碼如下:
176
340
495
652
807
961
1114
1268
1425
1579
1734
1888
2048
2201
2357
2521
2679
2834
2996
......
可以看到延遲是越來(lái)越嚴(yán)重的.
為了在js里可以使用相對(duì)準(zhǔn)確的計(jì)時(shí)功能,我們可以
復(fù)制代碼 代碼如下:
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);
代碼里,通過(guò)1000(也就是周期時(shí)間)減去當(dāng)前時(shí)間和準(zhǔn)確時(shí)間的差距,來(lái)算出下次觸發(fā)的時(shí)間,從而修正了當(dāng)前觸發(fā)的延遲.
下面是輸出
復(fù)制代碼 代碼如下:
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
......
可以看到雖然觸發(fā)時(shí)間并非絕對(duì)準(zhǔn)確,但由于每次觸發(fā)都進(jìn)行及時(shí)修正,所以并沒(méi)有造成誤差積累.
您可能感興趣的文章:
相關(guān)文章
JS圖片懶加載技術(shù)實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了JS圖片懶加載技術(shù)實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07JavaScript 動(dòng)態(tài)添加表格行 使用模板、標(biāo)記
在客戶端使用JavaScript動(dòng)態(tài)添加表格行,先到網(wǎng)上找了相關(guān)的資料,發(fā)現(xiàn)有現(xiàn)成做好的組件,發(fā)現(xiàn)它只能夠滿足比較簡(jiǎn)單的要求。2009-10-10bootstrap datetimepicker日期插件超詳細(xì)使用方法介紹
本篇文章主要介紹了bootstrap datetimepicker日期插件超詳細(xì)使用方法介紹,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02JS實(shí)現(xiàn)獲取GIF總幀數(shù)的方法詳解
如何通過(guò)js在上傳前就拿到它的總幀數(shù)來(lái)判斷呢?本文就跟大家分享一種解決方案,并將其封裝成插件發(fā)布至npm倉(cāng)庫(kù),快跟隨小編一起學(xué)習(xí)一下吧2022-05-05JS控制網(wǎng)頁(yè)動(dòng)態(tài)生成任意行列數(shù)表格的方法
這篇文章主要介紹了JS控制網(wǎng)頁(yè)動(dòng)態(tài)生成任意行列數(shù)表格的方法,實(shí)例分析了javascript操作表格節(jié)點(diǎn)控制dom元素添加的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03Antd?ProComponents中的EditableProTable無(wú)法在子行繼續(xù)新增子行的解決方案
這篇文章主要介紹了Antd?ProComponents中的EditableProTable無(wú)法在子行繼續(xù)新增子行的解決方案,本文通過(guò)復(fù)現(xiàn)代碼給大家詳細(xì)講解,需要的朋友可以參考下2022-08-08