TypeScript 中的非同步/等待
本文解釋了 TypeScript 中的非同步/等待。
YouTube Video
TypeScript 中的非同步/等待
async 是 TypeScript 中用來簡潔描述非同步操作的關鍵字,其行為與 JavaScript 的 async/await 語法相似。async 函數旨在使處理返回 Promise 的函數更加直觀。
async 函數的基礎
使用 async 關鍵字聲明的函數總是返回一個 Promise。以下是一個基本範例:。
1async function fetchData(): Promise<string> {
2 return "Data received";
3}
4
5fetchData().then((data) => console.log(data)); // "Data received"
在此範例中,由於 async 函數總是返回一個 Promise,因此返回值自動使用 Promise.resolve 進行解析。換句話說,"Data received" 變成了 Promise<string> 並被視為非同步操作。
await 關鍵字
await 關鍵字只能用於 async 函數內。這提供了一種能力,可以在繼續函數執行之前暫停並等待 Promise 的結果。
在以下範例中,使用 fetch 的非同步處理是以 async/await 的方式編寫的。
1async function getUserData() {
2 try {
3 const response = await fetch("https://codesparklab.com/json/example.json");
4 const data = await response.json();
5 console.log(data);
6 } catch (error) {
7 console.error("Error fetching user data:", error);
8 }
9}
10
11getUserData();在此範例中,await 用於等待 fetch 函數返回的 Promise 完成,其結果賦值給變數 response。此外,response.json() 的結果也使用 await 進行等待。
使用 async/await 的錯誤處理
非同步處理過程中發生的錯誤可使用標準的 try...catch 語法捕獲。如果在 await 的部分發生錯誤,該錯誤會在 catch 區塊中處理。
1async function fetchDataWithErrorHandling() {
2 try {
3 const response = await fetch('https://invalid.codesparklab.com/');
4 if (!response.ok) {
5 throw new Error(`HTTP error! status: ${response.status}`);
6 }
7 const data = await response.json();
8 console.log(data);
9 } catch (error) {
10 console.error("Fetch error:", error);
11 }
12}
13
14fetchDataWithErrorHandling();在上面的範例中,fetch 函數的結果是使用 await 等待的,如果發生錯誤,則用 try...catch 處理。
async/await 的優勢
-
直觀的非同步處理:通過使用
async/await,比起使用Promise鏈(then或catch),程式的流程更加直觀,可以像同步處理一樣編寫。 -
簡化錯誤處理:使用
try...catch簡化了非同步操作中的錯誤處理。比起使用Promise鏈,可以撰寫出更具可讀性的代碼。
async 函數的返回值
一個 async 函式總是返回一個 Promise。因此,即使沒有明確返回 Promise,透過使用 async 關鍵字也可以進行非同步處理。
1async function example() {
2 return 42;
3}
4
5example().then((result) => console.log(result)); // 42
在上述程式碼中,傳回了一個同步值 42,但因為它在 async 函式內,所以會自動轉換成 Promise.resolve(42)。
非同步函式的順序執行
依次執行多個非同步函式時,可以使用 await 來控制它們的順序。
1async function fetchData(url: string): Promise<any> {
2 try {
3 const response = await fetch(url);
4 return await response.json();
5 } catch (error) {
6 console.error("Error fetching user data:", error);
7 }
8}
9
10async function fetchData1(): Promise<any> {
11 return await fetchData("https://codesparklab.com/json/example.json");
12}
13
14async function fetchData2(): Promise<any> {
15 return await fetchData("https://codesparklab.com/json/example2.json");
16}
17
18async function processData() {
19 const data1 = await fetchData1();
20 console.log(data1);
21
22 const data2 = await fetchData2();
23 console.log(data2);
24}
25
26processData();在此範例中,會等待 fetchData1 完成後再執行 fetchData2。相較於使用 Promise 鍊,這種方式更具可讀性。
並行執行
如果希望並行執行非同步操作,可以使用 Promise.all 同時處理多個 Promise。
1async function fetchData(url: string): Promise<any> {
2 try {
3 const response = await fetch(url);
4 return await response.json();
5 } catch (error) {
6 console.error("Error fetching user data:", error);
7 }
8}
9
10async function fetchData1(): Promise<any> {
11 return await fetchData("https://codesparklab.com/json/example.json");
12}
13
14async function fetchData2(): Promise<any> {
15 return await fetchData("https://codesparklab.com/json/example2.json");
16}
17
18async function fetchMultipleData() {
19 const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
20 console.log(data1);
21 console.log(data2);
22}
23
24fetchMultipleData();在這種情況下,fetchData1 和 fetchData2 會同時執行,並在兩者都完成後繼續處理。這可以高效地處理多個非同步操作。
總結
- 一個
async函式會返回一個Promise,透過使用await關鍵字,可以等待非同步操作的結果。 - 透過使用
try...catch,非同步操作的錯誤處理變得更加簡單。 - 透過使用
Promise.all,可以並行執行多個非同步操作。
async/await 在 TypeScript 和 JavaScript 中被廣泛使用,因為它可以更簡潔地描述非同步操作。
您可以在我們的 YouTube 頻道上使用 Visual Studio Code 來跟隨上述文章一起學習。 請也查看我們的 YouTube 頻道。