Skip to main content

📄 Promise & async await

1. What is Promise ?

Promise 是 ES6 的新特性,主要是用來解決 callback hell 的問題,並且讓程式碼更容易閱讀。主要透過 .then.catch 兩種方法來處理。例如:

// 建立一個共用 function 來處理 api 請求
function fetchData(url) {
return fetch(url)
.then((response) => {
// 檢查 response 是否落在 200 ~ 299 的區間
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json(); // 將 response 轉成 json,並回傳
})
.catch((error) => {
// 檢查網路是否異常,或者請求被拒絕
console.log('There has been a problem with your fetch operation:', error);
throw error; // 將錯誤拋出
});
}

fetchData('https://jsonplaceholder.typicode.com/users/1')
.then((userData) => {
console.log('User data received:', userData);
})
.catch((error) => {
console.log('Error:', error.message);
});

2. 試判斷以下程式碼的輸出結果

本題包含有 event loop 的觀念

function a() {
console.log('Warlock');
}

function b() {
console.log('Druid');
Promise.resolve().then(() => {
console.log('Rogue');
});
}

function c() {
console.log('Mage');
}

function d() {
setTimeout(c, 100);
const temp = Promise.resolve().then(a);
console.log('Warrior');
setTimeout(b, 0);
}

d();

理解執行順序

首先看 d()

function d() {
setTimeout(c, 100); // 4. 非同步執行,延遲秒數為 100,故最後執行
const temp = Promise.resolve().then(a); // 2. 接續執行,並觸發 a()
console.log('Warrior'); // 1. 同步執行輸出
setTimeout(b, 0); // 3. 非同步執行,延遲秒數為 0
}

最終會拿到結果如下:

Warrior;
Warlock;
Druid;
Rogue;
Mage;

3. What is the output of the following snippet?

function printing() {
console.log(1);
setTimeout(function () {
console.log(2);
}, 1000);
setTimeout(function () {
console.log(3);
}, 0);

new Promise((resolve, reject) => {
console.log(4);
resolve(5);
}).then((foo) => {
console.log(6);
});

console.log(7);
}

printing();

// output ?

注意 Promise 的區塊

這題當初在面試時,對 Promise 的原理不夠熟悉,忽略了在 Promise 中 conoole.log(4) 所屬的區塊,不屬於非同步狀態(非 .then().catch()),因此在撰寫答案上,出現不小瑕疵。

1;
4;
7;
6;
3;
2;

這個運作順序邏輯如下,首先跑同步執行序,即 1, 4, 7 三組數字,而 setTimeout 中的 console.log 則依照 event loop 的機制,會先將非同步的程式碼放到 queue 中。同步任務執行完畢後,接著先執行 microtask queue 中的程式碼,因此會先執行 Promise 中的 console.log(6)。最後,開始執行非同步的任務,依照延遲秒數決定先後順序,因此印出 3, 2。