一、重要理論
? ? 1、JavaScript是單線程語(yǔ)言,所有任務(wù)都是同步執(zhí)行的。但是可以通過(guò)同步的方法實(shí)現(xiàn)異步執(zhí)行。
? ? 2、Event loop(事件循環(huán))是JS的執(zhí)行機(jī)制,也是JS實(shí)現(xiàn)異步執(zhí)行的一種方法。
????3、JS的執(zhí)行和運(yùn)行的區(qū)別
? ? ? ? ? ? JS可以在不同的環(huán)境中執(zhí)行,比如瀏覽器、node等,但是不同的環(huán)境執(zhí)行方式是不同的。
? ? ? ? ? ? 但是不管在那種環(huán)境下JS運(yùn)行是統(tǒng)一的,運(yùn)行是指JS的解析引擎。
二、JS的執(zhí)行機(jī)制
? ? 1、同步任務(wù)、異步任務(wù)
? ? 按照J(rèn)S是單線程語(yǔ)言的特點(diǎn),JS執(zhí)行機(jī)制應(yīng)該是所有的執(zhí)行任務(wù)都要排隊(duì)依次等待執(zhí)行。但這樣的速度肯定會(huì)很慢,這樣就有了同步任務(wù)和異步任務(wù)之分

? ? 如上圖,當(dāng)JS開始執(zhí)行后,所有的同步任務(wù)進(jìn)入主線程依次排隊(duì)執(zhí)行,異步任務(wù)則被送入Event Table中注冊(cè)函數(shù),當(dāng)指定的事件完成后由被送入Event Queue中等待主線程執(zhí)行棧的同步任務(wù)執(zhí)行完后調(diào)取異步任務(wù)的函數(shù)執(zhí)行。

? ? ? ? 如上圖代碼,setTimeout是異步任務(wù),console.log()是同步任務(wù),所以先執(zhí)行console.log(),setTimeout則被送入Event Table中等待定時(shí)3s后注冊(cè)函數(shù),再被送入Event Queue中進(jìn)入主程序執(zhí)行棧中執(zhí)行。
2、宏任務(wù)、微任務(wù)
? ? macro-task(宏任務(wù)): 整體JS代碼、setTimeout、setInterval
? ? micro-task(微任務(wù)):Promise、process.nextTick? ?

? ? 宏任務(wù)和微任務(wù)都有自己的Event Queue,各自進(jìn)入自己的Event Queue中等待執(zhí)行。上圖是事件循環(huán)的整體示意圖。當(dāng)一段代碼載入內(nèi)存中開始執(zhí)行后,整體代碼作為第一個(gè)宏任務(wù)開始執(zhí)行,如果有微任務(wù)的話送入對(duì)應(yīng)的Event Queue中,宏任務(wù)執(zhí)行完畢后再執(zhí)行微任務(wù),之后接著執(zhí)行宏任務(wù),就這樣循環(huán)依次執(zhí)行,稱之為事件循環(huán)(JS的執(zhí)行機(jī)制)。
