這是 JavaScript 用來處理「非同步」的語法,讓非同步程式碼看起來像同步程式碼一樣好讀。
點餐範例
//HTML:<button id="orderBtn">點餐</button>
// <p id="result"></p>
//js:
function makeFood() {
return new Promise((resolve) => {
setTimeout(() => {
resolve('蛋餅做好了!');
}, 2000); // 假裝要等 2 秒
});
}
async function orderBreakfast() {
document.getElementById('result').textContent = '製作中...';
const food = await makeFood(); // 等做好才往下走
document.getElementById('result').textContent = food;
}
document.getElementById('orderBtn').addEventListener('click', orderBreakfast);
大家可以將程式碼試著複製貼上操作看看
fetch
通常是用來發送網路請求的函式,通常放在你需要「跟伺服器要資料」的地方,搭配 await 一起用。
你可以把它想成:「跟瀏覽器說:幫我去問一下這個網址的伺服器,把資料拿回來給我。」
使用公開API作為例子
//HTML:<button id="loadBtn">取得資訊</button>
// <ul id="nameList"></ul>
//js:
async function getMenu() {
// 用一個真實可用的測試 API
const response = await fetch('https://jsonplaceholder.typicode.com/users'); // 發送請求,等伺服器回應
const data = await response.json(); // 把回應轉成 JSON 格式,一樣要等
console.log(data);
// 把資料顯示在畫面上
const list = document.getElementById('menuList');
list.innerHTML = ''; // 先清空
data.forEach(item => {
const li = document.createElement('li');
li.textContent = item.name;
list.appendChild(li);
});
}
document.getElementById('loadBtn').addEventListener('click', getMenu);
大方向說明
就這兩行是最常見的固定寫法,先記住這個模式就好。
什麼是 Promise?
你可以把 Promise 想成是「一張借據」,代表:
「我現在還沒有辦法給你真正的資料,但我保證之後會給你(不管是成功拿到,還是失敗)。」
Promise 有三種狀態:
| 狀態 | 意思 |
|---|---|
| pending(等待中) | 請求還在路上,還沒有結果 |
| fulfilled(成功) | 伺服器回應了,資料到手 |
| rejected(失敗) | 請求出錯了(網路斷線、伺服器掛掉等) |
為什麼需要 await?
await 就是「先停在這裡,等右邊這個 Promise 有結果了,才繼續往下執行」
飲料店範例
async function orderDrink() {
console.log('開始點餐');
const drink = await makeDrink(); // 停在這,等飲料做好
console.log('拿到飲料:', drink);
}
await 後面接的東西,必須是一個 Promise(或者說,是一個非同步操作)
程式碼寫起來雖然是「由上往下一行一行」,但實際上遇到 await 就會先暫停這個函式,等結果出來才繼續下一行
這樣寫的好處是:你可以用「同步」的寫法(由上而下讀),去處理「非同步」的邏輯,不用像 .then() 那樣一直串鏈
簡單記:await = 等這裡的結果出來,再往下走。