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