4.1 關鍵字 async
JavaScript中的非同步函數允許寫出看起來像同步的非同步代碼。
ECMAScript 2017 (ES8) 引入的關鍵字 async
和 await
,讓我們使用promises變得更簡單且代碼更易於理解和管理。
主要概念
在函數宣告前面使用關鍵字 async
表示這是一個非同步函數。非同步
函數總是返回一個promise,即使在其中未明確使用 return
。
如果函數返回一個值,它會自動被包裝在一個帶有該值的promise中。
語法:
async function name() {
// 函數代碼
}
範例:
JavaScript
async function greet() {
return 'Hello, world!';
}
greet().then((message) => {
console.log(message); // 會輸出:Hello, world!
});
4.2 關鍵字 await
關鍵字 await
用於在非同步函數中暫停它的執行,直到promise完成。await
只能在用關鍵字 async
聲明的函數中使用。
語法:
let result = await
promise;
範例:
JavaScript
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function greet() {
await delay(2000);
return 'Hello, world!';
}
async function displayGreeting() {
const message = await greet();
console.log(message); // 會輸出:Hello, world! 等待2秒後
}
displayGreeting();
4.3 使用 async 和 await 的示例
示例 1: 使用多個promise的非同步函數
JavaScript
function fetchData1() {
return new Promise((resolve) => setTimeout(() => resolve('Data 1'), 1000));
}
function fetchData2() {
return new Promise((resolve) => setTimeout(() => resolve('Data 2'), 2000));
}
async function fetchAllData() {
const data1 = await fetchData1();
console.log(data1); // 會輸出:Data 1 等待1秒後
const data2 = await fetchData2();
console.log(data2); // 會輸出:Data 2 等待2秒後
}
fetchAllData();
示例 2: 並行執行非同步操作
要並行執行多個非同步操作,可以用 Promise.all()
以及 await
。
JavaScript
function fetchData1() {
return new Promise((resolve) => setTimeout(() => resolve('Data 1'), 1000));
}
function fetchData2() {
return new Promise((resolve) => setTimeout(() => resolve('Data 2'), 2000));
}
async function fetchAllData() {
const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
console.log(data1); // 會輸出:Data 1 等待2秒後
console.log(data2); // 會輸出:Data 2 等待2秒後
}
fetchAllData();
示例 3: 使用 try...catch 進行錯誤處理
非同步函數允許使用 try...catch
區塊進行錯誤處理,使代碼更易讀和可管理。
JavaScript
function fetchDataWithError() {
return new Promise((resolve, reject) => setTimeout(() => reject('Error occurred'), 1000));
}
async function fetchData() {
try {
const data = await fetchDataWithError();
console.log(data);
} catch (error) {
console.error('Error:', error); // 會輸出:Error: Error occurred 等待1秒後
}
}
fetchData();
示例 4: 在類的方法中使用 async 和 await
非同步函數也可以用於類的方法中。
JavaScript
class DataFetcher {
async fetchData() {
const data = await new Promise((resolve) => setTimeout(() => resolve('Fetched Data'), 1000));
return data;
}
}
const fetcher = new DataFetcher();
fetcher.fetchData().then((data) => {
console.log(data); // 會輸出:Fetched Data 等待1秒後
});
示例 5: 非同步迭代器
非同步迭代器允許處理以非同步方式到達的資料流。
JavaScript
async function* asyncGenerator() {
let i = 0;
while (i < 3) {
await new Promise((resolve) => setTimeout(resolve, 1000));
yield i++;
}
}
async function iterateAsyncGenerator() {
for await (let value of asyncGenerator()) {
console.log(value); // 會輸出 0, 1 和 2,每隔1秒
}
}
iterateAsyncGenerator();
GO TO FULL VERSION