Javascript異步機制

Javascript作為一種單線程語言削樊,是如何實現(xiàn)異步編程的呢欲险?

相信不少人對Javascript單線程表示懷疑:為何單線程可以實現(xiàn)異步操作呢?其實Javascript確實是單線程的(我們不妨把這個線程稱作主線程)钦听,但它實現(xiàn)異步操作的方式確實借助了瀏覽器的其他線程的幫助椿争。那其他線程是怎么幫助Javascript主線程來實現(xiàn)異步的呢?答案就是任務隊列(task queue)和事件循環(huán)(event loop)缀棍。

一宅此、任務隊列

首先,作為單線程語言爬范,在Javascript中定義的任務都會在主線程中執(zhí)行父腕。但是并不是每個任務都會立刻執(zhí)行,而這種不立刻執(zhí)行的任務我們稱作異步任務青瀑。相反璧亮,那些立刻執(zhí)行的任務我們把它們稱作同步任務。而這些異步任務都會交給瀏覽器的其他線程去執(zhí)行斥难,但是主線程需要了解這些異步任務執(zhí)行的狀態(tài)枝嘶,才方便進行下一步操作。

打個比方哑诊,主線程準備做飯群扶,所以下達一個異步任務去買菜,異步任務買完菜之后得告訴主線程:“我買完菜啦”镀裤,這個時候主線程才好開始做飯竞阐。

而我們知道因為Javascript是單線程,所以上述的“下一步操作”沒法直接定義在主函數(shù)里(不然就被當做同步任務直接執(zhí)行了)暑劝,那這些應該定義在哪里呢骆莹?答案就是異步任務的回調(diào)函數(shù)中。在Javascript異步機制中铃岔,任務隊列就是用來維護異步任務回調(diào)函數(shù)的隊列汪疮。這樣一個隊列用來存放這些回調(diào)函數(shù)峭火,它們會等到主線程執(zhí)行完所有的同步函數(shù)之后按照先進先出的方式挨個執(zhí)行。那么執(zhí)行完任務隊列之后呢智嚷?Javascript主線程就執(zhí)行完畢了嗎卖丸?當然不是,不然網(wǎng)頁加載完畢之后盏道,誰來處理后續(xù)與用戶的交互事件(比如點擊事件)呢稍浆?

二、事件循環(huán)

javascript_asyc.jpg

我們通過上圖來更加形象的了解Javascript的異步機制猜嘱。
執(zhí)行同步任務 -> 檢查任務隊列中是否有任務 -> [有如果則執(zhí)行] -> 檢查任務隊列中是否有任務 -> [有如果則執(zhí)行] -> ......
可見主線程在執(zhí)行完同步任務之后衅枫,會無限循環(huán)地去檢查任務隊列中是否有新的“任務”,如果有則執(zhí)行朗伶。而這些任務包括我們在異步任務中定義的回調(diào)函數(shù)弦撩,也包括用戶交互事件的回調(diào)函數(shù)。通過事件循環(huán)论皆,Javascript不僅很好的處理了異步任務益楼,也很好的完成了與用戶交互事件的處理。因為在完成異步任務的回調(diào)函數(shù)之后点晴,任務隊列中的任務都是由事件所產(chǎn)生的感凤,因此我們也把上述的循環(huán)過程叫做事件循環(huán)

三粒督、異步機制實踐

console.log('定時器去買菜吧')
setTimeout(function(){
    console.log('菜買完了陪竿,主線程去做菜吧')
}, 0)
console.log('你先去買菜,我先看個世界杯')

在瀏覽器中執(zhí)行上述代碼屠橄,興許能更好地理解Javascript的異步機制族跛。

四、宏任務與微任務

宏任務:script锐墙、setTimeout庸蔼、setInterval、setImmediate贮匕、I/O、UI rendering
微任務:Promise(原生)花枫、process.nextTick
執(zhí)行順序:
事件循環(huán)的順序刻盐,決定js代碼的執(zhí)行順序。進入整體代碼(宏任務)后劳翰,開始第一次循環(huán)敦锌。接著執(zhí)行所有的微任務。然后再次從宏任務開始佳簸,找到其中一個任務隊列執(zhí)行完畢乙墙,再執(zhí)行所有的微任務颖变。
觀察者優(yōu)先級:
idle觀察者 > I/O觀察者 > check觀察者。
idle觀察者:process.nextTick
I/O觀察者:一般性的I/O回調(diào)听想,如網(wǎng)絡腥刹,文件,數(shù)據(jù)庫I/O等
check觀察者:setImmediate汉买,setTimeout

setTimeout(() => {
    console.log('timeout')
})
new Promise(function(resolve) {
    console.log('promise')
    resolve()
}).then(() => {
    console.log('then')
})
console.log('main')

執(zhí)行順序是:
promise衔峰、main、then蛙粘、timeout

五垫卤、總結

總而言之,Javascript單線程的背后有瀏覽器的其他線程為其完成異步服務出牧,這些異步任務為了和主線程通信穴肘,通過將回調(diào)函數(shù)推入到任務隊列等待執(zhí)行。主線程所做的就是執(zhí)行完同步任務后舔痕,通過事件循環(huán)评抚,不斷地檢查并執(zhí)行任務隊列中回調(diào)函數(shù)。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赵讯,一起剝皮案震驚了整個濱河市盈咳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌边翼,老刑警劉巖鱼响,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異组底,居然都是意外死亡丈积,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門债鸡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來江滨,“玉大人,你說我怎么就攤上這事厌均』;” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵棺弊,是天一觀的道長晶密。 經(jīng)常有香客問我,道長模她,這世上最難降的妖魔是什么稻艰? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮侈净,結果婚禮上尊勿,老公的妹妹穿的比我還像新娘僧凤。我一直安慰自己,他們只是感情好元扔,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布躯保。 她就那樣靜靜地躺著,像睡著了一般摇展。 火紅的嫁衣襯著肌膚如雪吻氧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天咏连,我揣著相機與錄音盯孙,去河邊找鬼。 笑死祟滴,一個胖子當著我的面吹牛振惰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播垄懂,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼骑晶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了草慧?” 一聲冷哼從身側響起桶蛔,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎漫谷,沒想到半個月后仔雷,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡舔示,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年碟婆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惕稻。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡竖共,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出俺祠,到底是詐尸還是另有隱情公给,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布蜘渣,位于F島的核電站妓布,受9級特大地震影響,放射性物質發(fā)生泄漏宋梧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一狰挡、第九天 我趴在偏房一處隱蔽的房頂上張望捂龄。 院中可真熱鬧释涛,春花似錦、人聲如沸倦沧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽展融。三九已至窖认,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間告希,已是汗流浹背扑浸。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留燕偶,地道東北人喝噪。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像指么,于是被迫代替她去往敵國和親酝惧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

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