公布答案嘍!
首先公布下答案,看看你做對多少嘞?
01
公布答案
第一題:

第二題:

第三題:

你答對了嗎?
02
知識儲備
宏任務和微任務都包含哪些,如下:
宏任務: script(整體代碼), setTimeout, setInterval, setImmediate, I/O(輸入輸出,比如讀取文件操作、網(wǎng)絡請求), UI rendering(dom渲染,即更改代碼重新渲染dom的過程),異步ajax等;
微任務: Promise(then、catch、finally)、async/await、process.nextTick(Node.js環(huán)境,在當前事件循環(huán)的末尾執(zhí)行的回調(diào)函數(shù))、Object.observe(?來實時監(jiān)測DOM對象的變化,已廢棄)、 MutationObserver(監(jiān)聽DOM樹的變化)。
注意:new Promise是同步任務
事件執(zhí)行順序:
首先執(zhí)行當前代碼(同步任務),直到遇到第一個宏任務或微任務。
如果遇到微任務,則將它添加到微任務隊列中,繼續(xù)執(zhí)行同步任務。
如果遇到宏任務,則將它添加到宏任務隊列中,繼續(xù)執(zhí)行同步任務。
當前任務執(zhí)行完畢后,JavaScript 引擎會先執(zhí)行所有微任務隊列中的任務,直到微任務隊列為空。
然后執(zhí)行宏任務隊列中的第一個任務,直到宏任務隊列為空。
重復步驟 4 和步驟 5,直到所有任務都被執(zhí)行完畢。 需要注意的是,微任務比宏任務優(yōu)先級要高,因此在同一個任務中,如果既有微任務又有宏任務,那么微任務會先執(zhí)行完畢。但具體問題還需具體分析。
在一些特殊情況下,微任務和宏任務的執(zhí)行順序可能會發(fā)生變化,比如在使用 MutationObserver 監(jiān)聽 DOM 變化時,它會被視為一個微任務,但是它的執(zhí)行順序可能會比其他微任務更靠后。
宏任務之間的執(zhí)行順序是:
setImmediate --> setTimeout --> setInterval --> i/o操作 --> 異步ajax
setImmediate沒有時間參數(shù),它與延遲 0 毫秒的 setTimeout() 回調(diào)?常相似。所以當setTimeout延遲時間也是0毫秒時,誰在前面就先執(zhí)行誰。此外如果setTimeout延遲時間不是0毫秒,它的執(zhí)行順序會在 i/o 操作之后。
微任務之間執(zhí)行的先后順序是:
process.nextTick --> Promise
03
解題
第一題:
1.函數(shù)定義,先跳過;
2.遇到setTimeout宏任務,放入宏任務隊列中,命名為time1;
3.遇到setTimeout宏任務,放入宏任務隊列中,命名為time2;
4.執(zhí)行Promise;
5.Promise.then,放入微任務隊列中,命名為then1;
6.執(zhí)行Promise;
7.Promise.then,放入微任務隊列中,命名為then2;
8.執(zhí)行Promise;
9.Promise.then,放入微任務隊列中,命名為then3;
9.執(zhí)行Promise;
10.Promise.then,放入微任務隊列中,命名為then4;
11.執(zhí)行fn函數(shù),輸出y,執(zhí)行Promise.solve;
12.遇await,將其放入微任務隊列,命名為await1;
13.回到主線程,輸出0;
14.根據(jù)先進先出規(guī)則,從微任務隊列取出任務 then1 到主線程中,輸出5;
15.從微任務隊列取出任務 then2 到主線程中,輸出6;
16.從微任務隊列取出任務 then3 到主線程中,輸出7;
17.從微任務隊列取出任務 then4 到主線程中,輸出8;
18.從微任務隊列取出任務 await1 到主線程中,輸出x,?此微任務隊列為空;
19.從宏任務隊列中取出 time1,輸出1,執(zhí)行Promise.resole;
20.遇Promise.then,放入微任務隊列,命名為then5;
21.從微任務隊列取出任務 then5 到主線程中,輸出2;
22.從宏任務隊列中取出 time2,輸出3,執(zhí)行Promise.resole;
23.遇Promise.then,放入微任務隊列,命名為then6;
24.從微任務隊列取出任務 then6 到主線程中,輸出4;
第二題:
1.遇setTimeout,放入宏任務隊列,命名為time1;
2.函數(shù)命名,忽略;
3.函數(shù)命名,忽略;
4.執(zhí)行async1,輸出1;
5.執(zhí)行async2,輸出2,resole();
6.遇Promise.then,將其放入微任務隊列,命名為then1;
7.回到主線程,new Promise,輸出3,執(zhí)行resolve;
8.遇Promise.then,將其放入微任務隊列,命名為then2;
9.從微任務隊列取出任務then1,輸出4,并return;
10.從微任務隊列取出任務then2,往下執(zhí)行,輸出5;
11.回到async1,遇到await,將其放入微任務隊列,命名為await1;
11.從微任務隊列取出任務await1,輸出6;
12.遇到async1.then,放入微任務隊列,命名為then3;
13.將微任務then3取出到主線程中,輸出7;
14.從宏任務隊列中取出 time1,輸出8
第三題:
1.函數(shù)命名,忽略;
2.函數(shù)命名,忽略;
3.輸出 script start;
4.遇setTimout,將其放入宏任務隊列,命名time1;
5.執(zhí)行async1,輸出 async1 start;
6.執(zhí)行async2,輸出 async2;
7.回到async1,遇await,將其放入微任務,命名await1;
8.new Promise,輸出 promise1;
9.Promise.then,將其放入微任務隊列,命名then1;
10.回到主線程,輸出 script end;
11.從微任務中取出await1,輸出 async1 end;
12.從微任務中取出then1,輸出 promise2;
13.從宏任務中取出time1,輸出 setTimeout;
04
拓展
看看這兩道題你能否答對呢?