js的回調(diào)及event-loop

參考文章:阮一峰

一、javascript是單線程

作為瀏覽器腳本語言,與使用用途有關(guān)決定了只能是單線程。

二、任務(wù)隊(duì)列

單線程意味著,所有任務(wù)需要排隊(duì),前一個任務(wù)結(jié)束,才會執(zhí)行后一份任務(wù),如果前一個任務(wù)耗時(shí)很長,后一個任務(wù)就不得不一致等待。
如果排隊(duì)是因?yàn)橛?jì)算量大,可以理解,但是很多時(shí)候CPU是閑著的,因?yàn)镮O設(shè)備(輸入輸出設(shè)備)很慢,比如(比如AJAX操作從網(wǎng)絡(luò)讀取數(shù)據(jù)),不得不等著結(jié)果出來,再往下執(zhí)行。
JavaScript設(shè)計(jì)者意識到,主線程可以不管IO設(shè)備,掛起處于等待中的任務(wù),先執(zhí)行排在后面的任務(wù),等到IO設(shè)備返回了結(jié)果,在繼續(xù)執(zhí)行掛起的任務(wù)。
于是,任務(wù)可以分成兩種,一種是同步任務(wù),另一種是異步任務(wù)。同步任務(wù)指在主線程排隊(duì)執(zhí)行的任務(wù),只有前一個任務(wù)執(zhí)行完畢,才能去執(zhí)行后面的任務(wù);異步任務(wù)指。不進(jìn)主線程,而是進(jìn)入任務(wù)隊(duì)列的任務(wù),只有任務(wù)隊(duì)列通知主線程,某個異步任務(wù)可以執(zhí)行了,該任務(wù)才會進(jìn)給主線程執(zhí)行。

  • 所有任務(wù)都在主線程上執(zhí)行,形成一個任務(wù)執(zhí)行棧。
  • 主線程外,還存在一個“任務(wù)隊(duì)列”,只要一步任務(wù)有了運(yùn)行結(jié)果,就在“任務(wù)隊(duì)列”之中放置一個事件。
  • 一旦“執(zhí)行?!敝兴型饺蝿?wù)執(zhí)行完畢,系統(tǒng)就會讀取“任務(wù)隊(duì)列”,看里面有哪些事件,那些異步任務(wù),結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。
  • 主線程不斷重復(fù)上面的第三步驟。
  • 當(dāng)主線程阻塞時(shí),任務(wù)隊(duì)列仍然是能夠被推入任務(wù)的,這也是為什么當(dāng)前頁面進(jìn)程阻塞時(shí)觸發(fā)的點(diǎn)擊事件會發(fā)進(jìn)程恢復(fù)后一次執(zhí)行。

只要主線程空了,就會去讀取“任務(wù)隊(duì)列”,這是Javescropt的運(yùn)行機(jī)制,這個過程會不斷的重復(fù)。

三、事件和回調(diào)函數(shù)

只要指定過回調(diào)函數(shù),這些事件發(fā)生時(shí)就會進(jìn)入“任務(wù)隊(duì)列”,等待主線程讀取。
所謂回調(diào)函數(shù),就是那些會被主線程掛起來的代碼。異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)主線程開始執(zhí)行異步任務(wù),就是執(zhí)行對應(yīng)的回調(diào)函數(shù)。
“任務(wù)隊(duì)列”是一個先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),排在前面的事件,優(yōu)先被主線程讀取。主線程的讀取過程基本是自動的,只要執(zhí)行棧一清空,“任務(wù)隊(duì)列”上第一位的事件就會自動進(jìn)入主線程,但是,由于存在“定時(shí)器”功能,主線程首先要檢查執(zhí)行時(shí)間,某些事件只有到了規(guī)定的時(shí)間,才能返回主線程。

四、Event Loop

主線程從“任務(wù)隊(duì)列”中讀取事件,這個過程是循環(huán)不斷的,所以著呢個運(yùn)行機(jī)制稱為Event Loop(事件循環(huán))。
執(zhí)行棧中的代碼(同步任務(wù)),總是在讀取“任務(wù)隊(duì)列”(異步任務(wù))之前執(zhí)行。

五、定時(shí)器

setTimeout()接受兩個參數(shù),第一個是回調(diào)函數(shù),第二個是推遲的毫秒數(shù)。
注意:
setTimeOut()只是將事件插入了“任務(wù)隊(duì)列”,必須等到當(dāng)前代碼(執(zhí)行棧)執(zhí)行完,主線程才會去執(zhí)行它指定的回調(diào)函數(shù)。如果當(dāng)前代碼耗時(shí)很長,有可能要等很久,所以并沒有辦法保證,毀掉函數(shù)一定會在setTimeout()指定的事件執(zhí)行。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容