聊一聊定時器里踩的坑

剛開始學(xué)習(xí) JavaScript 的時候硼讽,生搬硬套的知道了定時器是 JavaScript 中最基礎(chǔ)的異步操作曙聂,由于 JavaScript 是單線程腿箩,如果中間某個任務(wù)耗時過長律杠,后面的必須要等待块差,比如我們?yōu)g覽網(wǎng)頁的時候圖片會因為網(wǎng)絡(luò)原因加載的很慢,為了讓我們有更好的用戶體驗燎潮,我們可以把頁面骨架先渲染出來喻鳄,一些耗費資源的東西我們就通過異步來加載,可以通過一個圖示來感受一下:


image.png

同步和異步任務(wù)分別進入不同的執(zhí)行"場所"确封,同步的進入主線程除呵,異步的進入Event Table并注冊函數(shù);
當(dāng)指定的事情完成時,Event Table會將這個函數(shù)移入Event Queue;
主線程內(nèi)的任務(wù)執(zhí)行完畢為空爪喘,會去Event Queue讀取對應(yīng)的函數(shù)颜曾,進入主線程執(zhí)行;
上述過程會不斷重復(fù),也就是常說的Event Loop(事件循環(huán));

最開始接觸到異步相關(guān)的是 setTimeout 和 setInterval秉剑,對于一些輪詢的操作很方便泛豪,隨著接觸的深入,了解到事件隊列的概念,原來引擎還分為 JavaScript 引擎和定時器引擎诡曙,二者的執(zhí)行時機也是有先后的臀叙,即便 delay 設(shè)置為0,也是必須得主線程執(zhí)行完后不用等待可以馬上執(zhí)行价卤,而不是高于主線程的優(yōu)先級劝萤,結(jié)合代碼看一下:

setTimeout(function() {
  console.log('setTimeout')
}, 0)
console.log('我先執(zhí)行')
// 我先執(zhí)行
// setTimeout

從上述代碼中我們有個直觀的體會,就是定時器任務(wù)優(yōu)先級低于主線程任務(wù)荠雕,另外我們從 MDN 上看到定時器可以傳入多個參數(shù)稳其,分別是

var timeoutID = scope.setTimeout(function[, delay, param1, param2, ...])

這里傳入 function 和 delay 都是很常見的, delay 后面的參數(shù)是可選的炸卑,一旦定時器到期既鞠,它們會作為參數(shù)傳遞給 function;另外這里對于定時器的 id 需要了解一下盖文,timeoutID 是一個定時器的 id嘱蛋,這個值可以傳遞給 clearTimeout 來取消該定時器,并且 setTimeout 和 setInterval 共用一個編號池五续,所以你在代碼中調(diào)用 clearTimeout() 和 clearInterval() 效果相同洒敏,但是不建議混用。

setTimeout(function(a, b) {
  console.log(a+b)
}, 1000, 1, 2)

使用定時器輪詢接口

結(jié)合實際的業(yè)務(wù)場景來說吧疙驾,當(dāng)我們需要對于某個接口做輪詢的時候凶伙,自然就想到了定時器,最開始對于定時器的理解是 setTimeout 執(zhí)行一次就結(jié)束了它碎,setInterval 可以重復(fù)執(zhí)行函荣,所以輪詢的時候理所當(dāng)然的選擇了 setInterval,剛開始效果杠杠滴扳肛,可是過了一段時間如果網(wǎng)絡(luò)波動就會導(dǎo)致定時器不是那么 '準(zhǔn)時' 傻挂,當(dāng)時很奇怪,后面查找資料發(fā)現(xiàn)這是 setInterval 的一個弊端挖息,它指定的時間是每次執(zhí)行的間隔金拒,并不包含當(dāng)前請求消耗的時間,所以當(dāng)某次請求時間大于指定時間套腹,這個定時器就開始 '不準(zhǔn)'了绪抛,為了保證兩次執(zhí)行有固定的 delay,通過 setTimeout 來達(dá)到想要的效果电禀,看下代碼:

function interval(func, wait){
  var interv = function(){
    func.call(null)
    setTimeout(interv, wait)
  }
  setTimeout(interv, wait)
}

interval(function() {
  console.log(123)
  // 執(zhí)行相關(guān)操作
}, 1000)

通過上面的方式我們可以平滑的實現(xiàn)接口輪詢睦疫,以及類似的業(yè)務(wù),比如輪播圖等鞭呕。

還有就是了解一下 setTimeout 會出現(xiàn) this 指向全局的問題,不過現(xiàn)在使用箭頭函數(shù)就可以很方便避免這種問題了,不然你還得手動將 this 綁定回來葫松,比較麻煩

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瓦糕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子腋么,更是在濱河造成了極大的恐慌咕娄,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件珊擂,死亡現(xiàn)場離奇詭異圣勒,居然都是意外死亡,警方通過查閱死者的電腦和手機摧扇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門圣贸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人扛稽,你說我怎么就攤上這事吁峻。” “怎么了在张?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵用含,是天一觀的道長。 經(jīng)常有香客問我帮匾,道長啄骇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任瘟斜,我火速辦了婚禮缸夹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘哼转。我一直安慰自己明未,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布壹蔓。 她就那樣靜靜地躺著趟妥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪佣蓉。 梳的紋絲不亂的頭發(fā)上披摄,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機與錄音勇凭,去河邊找鬼疚膊。 笑死,一個胖子當(dāng)著我的面吹牛虾标,可吹牛的內(nèi)容都是我干的寓盗。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼傀蚌!你這毒婦竟也來了基显?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤善炫,失蹤者是張志新(化名)和其女友劉穎撩幽,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箩艺,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡窜醉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了艺谆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片榨惰。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖擂涛,靈堂內(nèi)的尸體忽然破棺而出读串,到底是詐尸還是另有隱情,我是刑警寧澤撒妈,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布恢暖,位于F島的核電站,受9級特大地震影響狰右,放射性物質(zhì)發(fā)生泄漏杰捂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一棋蚌、第九天 我趴在偏房一處隱蔽的房頂上張望嫁佳。 院中可真熱鬧,春花似錦谷暮、人聲如沸蒿往。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瓤漏。三九已至,卻和暖如春颊埃,著一層夾襖步出監(jiān)牢的瞬間蔬充,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工班利, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留饥漫,地道東北人。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓罗标,卻偏偏與公主長得像庸队,于是被迫代替她去往敵國和親积蜻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容