大家好,我是IT修真院武漢第10期學(xué)員缕溉,一枚正直、純潔吃型、善良的前端程序員证鸥。
今天給大家分享一下,修真院官網(wǎng)任務(wù)JS-task1,深度思考的知識(shí)點(diǎn)——什么是定時(shí)器枉层?有什么用泉褐?
1.背景介紹
瀏覽器(或者說JS引擎)執(zhí)行JS的機(jī)制是基于事件循環(huán)。
由于JS是單線程鸟蜡,所以同一時(shí)間只能執(zhí)行一個(gè)任務(wù)膜赃,其他任務(wù)就得排隊(duì),后續(xù)任務(wù)必須等到前一個(gè)任務(wù)結(jié)束才能開始執(zhí)行揉忘。
為了避免因?yàn)槟承╅L(zhǎng)時(shí)間任務(wù)造成的無意義等待跳座,JS引入了異步的概念,用另一個(gè)線程來管理異步任務(wù)泣矛。
同步任務(wù)直接在主線程隊(duì)列中順序執(zhí)行疲眷,而異步任務(wù)會(huì)進(jìn)入另一個(gè)任務(wù)隊(duì)列,不會(huì)阻塞主線程您朽。等到主線程隊(duì)列空了(執(zhí)行完了)的時(shí)候狂丝,就會(huì)去異步隊(duì)列查詢是否有可執(zhí)行的異步任務(wù)了(異步任務(wù)通常進(jìn)入異步隊(duì)列之后還要等一些條件才能執(zhí)行,如ajax請(qǐng)求哗总、文件讀寫)几颜,如果某個(gè)異步任務(wù)可以執(zhí)行了便加入主線程隊(duì)列,以此循環(huán)讯屈。
JS定時(shí)器
JS的定時(shí)器目前有三個(gè):setTimeout蛋哭、setInterval和setImmediate。
定時(shí)器也是一種異步任務(wù)耻煤,通常瀏覽器都有一個(gè)獨(dú)立的定時(shí)器模塊具壮,定時(shí)器的延遲時(shí)間就由定時(shí)器模塊來管理,當(dāng)某個(gè)定時(shí)器到了可執(zhí)行狀態(tài)哈蝇,就會(huì)被加入主線程隊(duì)列棺妓。
JS定時(shí)器非常實(shí)用,做動(dòng)畫的肯定都用到過炮赦,也是最常用的異步模型之一怜跑。
有時(shí)候一些奇奇怪怪的問題,加一個(gè)setTimeout(fn, 0)(以下簡(jiǎn)寫setTimeout(0))就解決了吠勘。不過性芬,如果對(duì)定時(shí)器本身不熟悉,也會(huì)產(chǎn)生一些奇奇怪怪的問題剧防。
2.知識(shí)剖析
setTimeout
setTimeout(fn, x)表示延遲x毫秒之后執(zhí)行fn植锉。
使用的時(shí)候千萬不要太相信預(yù)期,延遲的時(shí)間嚴(yán)格來說總是大于x毫秒的峭拘,至于大多少就要看當(dāng)時(shí)JS的執(zhí)行情況了俊庇。另外狮暑,多個(gè)定時(shí)器如不及時(shí)清除(clearTimeout),會(huì)存在干擾辉饱,使延遲時(shí)間更加捉摸不透搬男。所以,不管定時(shí)器有沒有執(zhí)行完彭沼,及時(shí)清除已經(jīng)不需要的定時(shí)器是個(gè)好習(xí)慣缔逛。HTML5規(guī)范規(guī)定最小延遲時(shí)間不能小于4ms,即x如果小于4姓惑,會(huì)被當(dāng)做4來處理褐奴。 不過不同瀏覽器的實(shí)現(xiàn)不一樣,比如挺益,Chrome可以設(shè)置1ms歉糜,IE11/Edge是4ms。setTimeout注冊(cè)的函數(shù)fn會(huì)交給瀏覽器的定時(shí)器模塊來管理望众,延遲時(shí)間到了就將fn加入主進(jìn)程執(zhí)行隊(duì)列匪补,如果隊(duì)列前面還有沒有執(zhí)行完的代碼,則又需要花一點(diǎn)時(shí)間等待才能執(zhí)行到fn烂翰,所以實(shí)際的延遲時(shí)間會(huì)比設(shè)置的長(zhǎng)夯缺。如在fn之前正好有一個(gè)超級(jí)大循環(huán),那延遲時(shí)間就不是一丁點(diǎn)了甘耿。
setInterval
setInterval的實(shí)現(xiàn)機(jī)制跟setTimeout類似踊兜,只不過setInterval是重復(fù)執(zhí)行的。 對(duì)setInterval(fn, 100)容易產(chǎn)生一個(gè)誤區(qū):并不是上一次fn執(zhí)行完了之后再過100ms才開始執(zhí)行下一次fn佳恬。 事實(shí)上捏境,setInterval并不管上一次fn的執(zhí)行結(jié)果,而是每隔100ms就將fn放入主線程隊(duì)列毁葱,而兩次fn之間具體間隔多久就不一定了垫言,跟setTimeout實(shí)際延遲時(shí)間類似,和JS執(zhí)行情況有關(guān)倾剿。
3.常見問題
定時(shí)器引起的代碼超級(jí)無敵托馬斯回旋式爆炸阻塞
4.解決方案
清除定時(shí)器唄~
5.編碼實(shí)戰(zhàn)
還有那些方法可以實(shí)現(xiàn)定時(shí)器或類似定時(shí)器的效果筷频?
Promise
Promise是很常用的一種異步模型,如果我們想讓代碼在下一個(gè)事件循環(huán)執(zhí)行前痘,可以選擇使用setTimeout(0)凛捏、setImmediate、requestAnimationFrame(Chrome)和Promise芹缔。而且Promise的延遲比setImmediate更低坯癣,意味著Promise比setImmediate先執(zhí)行。
6.擴(kuò)展思考
7.參考文獻(xiàn)
8.更多討論
詳情請(qǐng)看:
Q1:在我們?nèi)粘9ぷ髦凶钋罚心男┑胤綍?huì)用到定時(shí)器坡锡?
答:動(dòng)畫蓬网。
Q2:除了前文提到的兩種常用的定時(shí)器,你還接觸過哪些定時(shí)器的使用鹉勒?
答:promise。
Q3:在定時(shí)器的使用過程中可能存在哪些問題吵取?
答:代碼阻塞禽额。