前言:
javascript提供兩個定時器方法來實現(xiàn)定時的效果,setIterval和setTimeout,同時提供兩個清除定時器的方法clearInterl和clearTimeout.
一谷婆、定時器的作用:
延遲腳本執(zhí)行
自動執(zhí)行重復(fù)操作
二还绘、定時器的特點(以下均以setTimeout為示例,setInterval原理一樣)
1.定時器的執(zhí)行順序
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i)
}, 10)
}
執(zhí)行以上代碼,發(fā)現(xiàn)控制臺打印出5個5,原因:
javascript是單線程,setTimeout是一個異步任務(wù),js引擎在執(zhí)行javascript任務(wù)時,會先執(zhí)行所有在js引擎任務(wù)中的代碼,在本例中,js引擎從上往下執(zhí)行,發(fā)現(xiàn)setTimeout異步任務(wù),把任務(wù)推到任務(wù)隊列中,待10ms后(本例setTimeout設(shè)置的時間是10ms),setTimeout任務(wù)被加到j(luò)s主線程中,若此時沒有其他任務(wù),則setTimeout任務(wù)被執(zhí)行,若仍然存在其他任務(wù),則setTimeout待其他任務(wù)被執(zhí)行完成后才開始執(zhí)行.本例中,每個setTimeout任務(wù)設(shè)置的時間均為10ms,若在10ms的時間內(nèi)for循環(huán)沒有執(zhí)行完,那么setTimeout任務(wù)則會等待超過10ms的時間,一直到for循環(huán)執(zhí)行完之后才會被執(zhí)行.由此也可以說明,定時器的時間并不是完全準(zhǔn)確,會大于或者等于設(shè)置的時間.
2.定時器id
看下面一段代碼:
var timer = setTimeout (function () {...}, 10)
console.log(timer) // 數(shù)字
timer實際上是定時器的id,是一個數(shù)字,把timer傳入clearTimeout中可以用來清除定時器,在遇到多個定時器的場景,為了避免一個定時器任務(wù)執(zhí)行時其他定時器的影響,一般將所有的定時器id放到數(shù)組中,某一個定時器任務(wù)執(zhí)行時,遍歷清除數(shù)組中其他定時器任務(wù),從而消除其他定時器的影響.
3.setTimeout和setInterval的區(qū)別
setTimeout,指定一個setTimeout任務(wù),只執(zhí)行一次
setInterval,指定一個setInterval任務(wù),無限執(zhí)行,直至被clearInterval清除才停止
4.定時器的巧妙運用
定時器在項目中除了可以作為定時的作用外還可以用來做耗時代碼的優(yōu)化:
我們假設(shè)有這樣的一個場景纫版,就是在某個頁面中要渲染50萬個節(jié)點,這個時候?qū)τ谝话愕捻椖恐衅茄唬苯愉秩臼遣豢扇〉呐可驗檫@個時候會占用過多的內(nèi)存杠河,導(dǎo)致瀏覽器出現(xiàn)了卡死的狀態(tài),用戶誤以為是頁面卡死而 直接關(guān)閉瀏覽器或者殺死進程傻咖,即使是用戶不關(guān)閉頁面這樣給用戶的體驗也是不好的朋魔,這個時候我們要怎樣來解決這個問題呢,我們可以利用定時器來優(yōu)化這個問題首先我們可以把50萬個節(jié)點分成多組卿操,每組渲染的節(jié)點數(shù)不要過多警检,然后通過setInterval來進行循環(huán)這個既不阻塞JS引擎線程的運行孙援,又可以提高渲染的消耗時間。從而達到最終的優(yōu)化渲染.