如果 await
的 promise 失敗,會丟出錯誤,類似 throw new Error
的效果:
async function f1() {
await Promise.reject(new Error("Whoops!"));
}
// 等同於
async function f2() {
throw new Error("Whoops!");
}
錯誤處理也可以像同步任務使用 try...catch
:
async function f() {
try {
let response = await fetch('/no-user-here');
let user = await response.json();
} catch(err) {
console.log(err);
}
}
f();
如果沒有 try...catch
,async
函式產生的 promise 狀態會變成 rejected,此時也可以在函式上加上 .catch
處理 (如下),不加的話就會出現 uncaught error。通常使用 async/ await
後就不太需要 .then/ .catch
,但當例如在函式外面、語法上不允許使用 await
時,.then/ .catch
也是一種選擇。
async function f() {
let response = await fetch('http://no-such-url');
}
f().catch(alert); // TypeError: failed to fetch
async function loadJson(url) {
let response = await fetch(url);
if (response.status == 200) {
let json = await response.json(); // (5)
return json;
}
throw new Error(response.status);
}
loadJson('https://javascript.info/no-such-user.json')
.catch(alert); // Error: 404
教學中寫到這段範例的第 5 行「也可以直接寫 return response.json();
,但在外面的程式碼就需要 await
結果」。雖然這段只是寫法練習沒有太多情境,但如果是要回傳 JSON 到 loadJson
外面使用,以現在第 5、6 行的寫法函式外也是需要 await
結果,因為函式無論如何都會回傳 promise。所以原則應該是有需要等待結果的地方都要加上 await
,這部分可能會因為太像在寫同步程式碼而忘記。