函數調用棧:(call stack)
index.js

特點:先入棧,先執行。(從上往下執行,就代碼的執行順序)執行前入棧,執行后出棧。a先執行完 a先出棧,后續就是B出棧,接着就是整個全局上下文出棧,成為空棧。
任務隊列:(task queue)
隊列特點: 先進先出。
在單線程的js中,任務分為同步任務和異步任務。
同步任務:在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行后一個任務。
異步任務:同樣在主線程執行,只是將異步任務加入到任務隊列中或者事件隊列中,等主線程的同步任務執行完畢,就執行任務隊列中的事件,事件對應的事件處理函數,加入前面所講的函數執行棧執行。

輸出結果是 "1" "2" "set2" "setTimeout"
第一步: setTimeout 是個異步任務,回調函數加入任務隊列,主線程先執行后續的任務。
第二步:for循環同步任務, console.log("1") 先進棧,后出棧。
第三步: setTimeout 跟第一步處理一致。
第四步: for循環同步任務 console.log("2") 先進戰。后出棧。
第五步: 棧任務完成之后,會不斷輪詢,任務隊列中的回調函數,回調函數重新進入主線程的調用棧,輸出數據,完成出棧。
事件輪詢(Event Loop): 只要異步任務中的等待時間結束后,觸發事件處理函數,該函數就會被推入函數執行棧。不斷重復這個過程,就是事件輪詢。
setTimeout: 表明的是等待多少毫秒后,將事件處理程序推入到函數執行棧,並不是等待多少毫秒后立馬執行該事件處理程序,什么時候執行,要取決於當前主進程有沒有相關任務在執行,如果前面沒有相關任務,就會讀取該任務執行。

宏任務與微任務:
宏任務: 主進程代碼、setTimeout里的回調、setInterval回調
微任務: promise.then catch finally 等

執行順序: 主進程宏任務(主進程代碼) ---> 主進程微任務(promise.then) ---> 異步隊列里的宏任務(定時器回調)
實例: 輸出: 外層宏事件1 外層宏事件2 微事件1 微事件2 內層宏事件3
setTimeout(() => { //執行后 回調一個宏事件 console.log('內層宏事件3') }, 0) console.log('外層宏事件1'); new Promise((resolve) => { console.log('外層宏事件2'); resolve() }).then(() => { console.log('微事件1'); }).then(()=>{ console.log('微事件2') })
