JavaScript 核心觀念(79) - ES6 章節:Async/Await - 為什麼要使用 Async 與基本介紹

前言

接下來將會進入新的章節,也就是 Async 與 Await,所以接下來將會了解為什麼要使用 Async 與 Await 跟怎麼使用它。

為什麼要使用 Async 與基本介紹

首先準備進入該章節之前,會建議多了解一下 Promise 會較好,因為 Async 與 Await 中的許多觀念都跟 Promise 有相對應的觀念。

因此接下來看一段範例程式碼

1
2
3
4
5
6
7
8
9
10
11
function promiseFn (boolean) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(boolean) {
resolve('resolve');
} else {
reject('reject')
}
}, 1000)
})
}

上面這一段程式碼就不多描述運作了,簡單來講當我們使用這個 promiseFn 時可以這樣用

1
2
3
4
5
6
7
promiseFn(true)
.then((res) => {
console.log('resolve', res);
})
.catch((err) => {
console.log('reject', err);
})

那如果今天是 Async 與 Await 呢?首先 Async 是必須寫在宣告函式之前,如以下

1
2
3
4
5
6
7
8
9
10
11
async function fn() {
...
}

const fn = async function() {
...
}

const fn = async () => {
...
}

那麼接下來要如何將上面呼叫 promiseFn 的方式改寫呢?其實就是使用 Async 來重寫

1
2
3
4
5
6
async function asyncFn() {
const res = await promiseFn(true);
console.log(res); // resolve
}

asyncFn();

這邊要注意 await 僅會用於接收 Promise 表達式結果,而使用 await 之後程式碼會被迫堵塞住等待該行執行完畢,因此就會有點類似逐行執行的概念運作,也就不會發生事件佇列(非同步)的狀況發生。

1
2
3
4
5
6
7
async function asyncFn() {
console.log('1'); // 1
const res = await promiseFn(true);
console.log('2', res); // 2 resolve
}

asyncFn();

而這邊假設如果要如前面 Promise 一樣可以接下一個 then 的話該怎麼撰寫呢?其實非常簡單

1
2
3
4
5
6
7
8
9
async function asyncFn() {
console.log('1'); // 1
const res1 = await promiseFn(true);
console.log('2', res1); // 2 resolve
const res2 = await promiseFn(true);
console.log('3', res2); // 3 resolve
}

asyncFn();

因此整體來講 Async 與 Await 可以說是真正解決 Promise 的聖經語法,讓整體閱讀性更高。

但實務開發上來講必定會遇到錯誤,那錯誤發生時該怎麼做呢?那這時候就要使用錯誤捕捉的方式

1
2
3
4
5
6
7
8
9
10
11
12
async function asyncFn() {
try {
console.log('1'); // 1
const res1 = await promiseFn(true);
console.log('2', res1); // 2 resolve
const res2 = await promiseFn(false); // 製造失敗
} catch(error) {
console.log('error', error);
}
}

asyncFn();

只是在這邊要注意一件事情,使用 try...catch... 之後就無法在失敗之後再次執行特定行為。

參考文獻