JavaScript Promise的錯誤處理
阿新 • • 發佈:2022-04-17
今天我們來學習在Promise中如何處理異常錯誤。
假設有一個getUserById
函式用來獲取使用者,它返回一個promise。
function getUserById(id) { return new Promise((resolve, reject) => { resolve({ id: id, username: 'admin' }); }); }
throw new Error
在返回promise之前,如果id引數不合法throw一個異常
function getUserById(id) { if (typeof id !== 'number' || id <= 0) {throw new Error('引數ID不合法'); } return new Promise((resolve, reject) => { resolve({ id: id, username: 'admin' }); }); }
接著,呼叫這個promise,設定then、catch回撥
getUserById('a') .then(user => console.log(user.username)) .catch(error => console.log(error)); // 輸出: // Uncaught Error: 引數ID不合法
可以看到,then、catch都不會走,如果要捕獲這個錯誤,必須要用try/catch
try { getUserById('a') .then(user => console.log(user.username)) .catch(error => console.log(`.catch被呼叫:${error}`)); } catch (error) { console.log(`try/catch被呼叫:${error}`); } // 輸出: // try/catch被呼叫:Error: 引數ID不合法
在try/catch內成功捕獲錯誤。
在Promise內throw
在promise內丟擲異常
let authorized = false; function getUserById(id) { return new Promise((resolve, reject) => { if (!authorized) { throw new Error('未登入,獲取使用者資訊失敗'); } resolve({ id: id, username: 'admin' }); }); }
呼叫
try { getUserById(10) .then(user => console.log(user.username)) .catch(error => console.log(`.catch被呼叫:${error}`)); } catch (error) { console.log(`try/catch被呼叫:${error}`); } // 輸出: // .catch被呼叫:Error: 未登入,獲取使用者資訊失敗
如果在promise內去throw丟擲異常,則可以在.catch的回撥中捕獲到,在try/catch中無法捕獲
如果使用鏈式呼叫promise,.catch將捕獲任何一個promise的異常錯誤
promise1 .then(promise2) .then(promise3) .then(promise4) .catch(err => console.log(err));
在上面的例子裡,如果promise1、promise2有異常都會被.catch捕獲到。
使用reject()
函式
使用reject()函式和上面throw丟擲異常一樣,
let authorized = false; function getUserById(id) { return new Promise((resolve, reject) => { if (!authorized) { reject('未登入,獲取使用者資訊失敗'); } resolve({ id: id, username: 'admin' }); }); } try { getUserById(10) .then(user => console.log(user.username)) .catch(error => console.log(`.catch被呼叫:${error}`)); } catch (error) { console.log(`try/catch被呼叫:${error}`); } // 輸出: // .catch被呼叫:未登入,獲取使用者資訊失敗
在上面例子裡,我們沒有在promise內throw異常,而是呼叫reject()函式。同樣也是在.catch被捕獲。
沒有.catch()方法會怎樣
下面的例子裡沒有為promise提供.catch回撥來捕獲錯誤
let authorized = false; function getUserById(id) { return new Promise((resolve, reject) => { if (!authorized) { reject('未登入,獲取使用者資訊失敗'); } resolve({ id: id, username: 'admin' }); }); } try { getUserById(10) .then(user => console.log(user.username)); // 下面的程式碼會執行 console.log('next'); } catch (error) { console.log(`try/catch被呼叫:${error}`); } // 輸出: // next // Uncaught (in promise) 未登入,獲取使用者資訊失敗
如果promise被resolve,則可以省略catch()回撥。上面console.log('next')將會執行。
總結
在promise中,.catch()函式會捕獲promise內的throw錯誤和reject丟擲的錯誤。
如果promise發生異常,而沒有.catch()函式,也會在控制檯丟擲異常,但後面的程式碼依舊會執行。