最近公司遭逢重大變故,開始面試看看其他機會。看看自己怠惰的行為,已經四個月沒有更新了 (汗)。
不過有面試就有收穫,苦無素材的時候。面試題目就如同及時雨一般,在心中種下新文章的種子。
好了! 幹的不講太多了。看一下這次碰到不錯的題目以及解題技巧吧!
async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); } async function async2() { console.log("async2"); } console.log("script start"); setTimeout(function () { console.log("setTimeout"); }) async1(); new Promise(function (resolve) { console.log("promise1"); resolve(); }).then(function () { console.log("promise2"); }) console.log("script end"); // 解釋最後輸出的結果
先搞清楚這題在考什麼!沒錯已經寫在文章標題 — Event Loop
好! 關於 event loop 的概述,我必須為自己的文章導流一下: Macrotask 和 microtask
這邊直接講解題技巧
第一步 : 勇敢的先畫兩條分隔線,區隔同步事件和非同步事件還有 Timeout 事件
// ========= 非同步事件分隔線 ====== // ========= TimeOut 事件 ========
第二步 : SetTimeout
setTimeout
會在 Event Loop 的最後執行,是因為它被放置在事件循環的 “任務佇列”(Task Queue)中。所以看到 setTimeout 裡面的內容,勇敢的移到最後面就對了!
"script start" // ========= 非同步事件分隔線 ====== // ========= TimeOut 事件 ======== "setTimeout"
第三步 : 冷靜三秒,想一下 async / await 在幹嘛!
在 async
函數中使用 await
關鍵字時,await
會暫停該函數的執行,等待 Promise 解決後繼續執行。await
的回傳值是該 Promise 解決(fulfilled)後的值。
這是 await
的一些要點:
- 如果
await
遇到一個 Promise,會等待該 Promise 解決並返回解決的值。 - 如果
await
遇到的不是 Promise,它會將該值轉換為一個已解決的 Promise,並返回該值。
簡單來說, await 後面的函式,就是會跑下去,如果遇到同步執行的指令,就是跑下去。遇到 Promise 就會跑到 Promise 分隔線後面。
// 為方便講解,把 async1, async2 貼上來 async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); } async function async2() { console.log("async2"); } async1(); "script start" "async1 start" // 第一個同步處理 "async2" // 進入 async2 因為裡面沒有 promise 內容,所以做裡面同步處理的內容 // ========= 非同步事件分隔線 ====== "async1 end" // 被 await 擋住,所以會被排到非同步處理完成後執行 // ========= TimeOut 事件 ======== "setTimeout"
第四步 : Promise
觀念換湯不換藥,console.log(“promise1”) 是一個同步處理事件, resolve 可以觸發 Primse 完成,並執行接下來的非同步處理流程 then 裡面的 function。
// 為方便講解把題目放上來 new Promise(function (resolve) { console.log("promise1"); resolve(); }).then(function () { console.log("promise2"); }) console.log("script end") // 這是同步處理的最後一個 task // 最終得到的輸出順序如下: "script start" "async1 start" "async2" "promise1" // Promise 同步處理的 fuction "script end" // 題目想要考你的小陷阱 // ========= 非同步事件分隔線 ====== "async1 end" "promise2" // 要等 resolve 的結果,所以一律排到後面去。 // ========= TimeOut 事件 ======== "setTimeout"
好,以上是我自己的解題技巧,希望對大家有幫助。