1. 程式人生 > 其它 >JavaScript Promise的錯誤處理

JavaScript Promise的錯誤處理

今天我們來學習在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()函式,也會在控制檯丟擲異常,但後面的程式碼依舊會執行。