一、JavaScript是單線程的炎滞,意味著所有任務(wù)需要排隊(duì)敢艰,一個(gè)任務(wù)執(zhí)行完,才能執(zhí)行下一個(gè)任務(wù)册赛。當(dāng)進(jìn)行像I/O這種耗時(shí)操作任務(wù)時(shí)钠导,下一個(gè)任務(wù)會(huì)被阻塞一直掛起。為解決這個(gè)問題森瘪,JavaScript把任務(wù)分成:同步任務(wù)和異步任務(wù)辈双。
1、同步任務(wù):在主線程上排隊(duì)執(zhí)行的任務(wù)柜砾,只有前一個(gè)任務(wù)執(zhí)行完畢,才能執(zhí)行后一個(gè)任務(wù)换衬。
2痰驱、異步任務(wù):不進(jìn)入主線程、而進(jìn)入"任務(wù)隊(duì)列"(task queue)瞳浦,只有"任務(wù)隊(duì)列"通知主線程担映,某個(gè)異步任務(wù)可以執(zhí)行了,該任務(wù)才會(huì)進(jìn)入主線程執(zhí)行叫潦。
在所有同步任務(wù)執(zhí)行完之前蝇完,任何的異步任務(wù)是不會(huì)執(zhí)行的。
二矗蕊、理解Event Loop
1短蜕、所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack)傻咖。
2朋魔、主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"(task queue)卿操。只要異步任務(wù)有了運(yùn)行結(jié)果警检,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。
3害淤、一旦"執(zhí)行棧"中的所有同步任務(wù)執(zhí)行完畢扇雕,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列",看看里面有哪些事件窥摄。那些對(duì)應(yīng)的異步任務(wù)镶奉,于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行腮鞍。
4值骇、主線程不斷重復(fù)上面的第三步。
主線程從"任務(wù)隊(duì)列"中讀取事件移国,這個(gè)過程是循環(huán)不斷的吱瘩,所以整個(gè)的這種運(yùn)行機(jī)制又稱為Event Loop(事件循環(huán))。只要主線程空了迹缀,就會(huì)去讀取"任務(wù)隊(duì)列"使碾,這就是JavaScript的運(yùn)行機(jī)制。
一般來說祝懂,有以下四種會(huì)放入異步任務(wù)隊(duì)列:
1票摇、setTimeout和setlnterval
2、DOM事件
3砚蓬、ES6中的Promise
4矢门、Ajax異步請(qǐng)求