欣迪

最近公司遭逢重大變故,開始面試看看其他機會。看看自己怠惰的行為,已經四個月沒有更新了 (汗)。

不過有面試就有收穫,苦無素材的時候。面試題目就如同及時雨一般,在心中種下新文章的種子。

好了! 幹的不講太多了。看一下這次碰到不錯的題目以及解題技巧吧!

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 的一些要點:

  1. 如果 await 遇到一個 Promise,會等待該 Promise 解決並返回解決的值。
  2. 如果 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"

好,以上是我自己的解題技巧,希望對大家有幫助。

訂閱 IT-Monk

訂閱最新文章的發布消息! 😚😚😚
Loading

作者介紹 - 欣迪

欣迪

從設計到寫程式,發現自己有追求前端技巧的自虐傾向。不斷的踩坑,再從坑裡爬出來,慢慢對攀岩有點心得。 目前在多間公司擔任網站設計顧問。 同時也是網站架設公司負責人。