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()函數,也會在控制台拋出異常,但后面的代碼依舊會執行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM