В этом руководстве вы узнаете, как работать с обработкой ошибок в промисах в JavaScript.
Предположим, у вас есть функция с именем getUserById()
, которая возвращает промис:
function getUserById(id) { return new Promise((resolve, reject) => { resolve({ id: id, username: 'admin' }); }); }
Обычная ошибка
- Во-первых, измените
getUserById()
, чтобы она выдавала ошибку вне промиса:
function getUserById(id) { if (typeof id !== 'number' || id <= 0) { throw new Error('Invalid id argument'); } return new Promise((resolve, reject) => { resolve({ id: id, username: 'admin' }); }); }
- Во-вторых, обработайте обещание, используя оба метода
then()
иcatch()
:
getUserById('a') .then(user => console.log(user.username)) .catch(err => console.log(err));
Код выдает ошибку:
Uncaught Error: Invalid id argument
Когда вы создаете исключение вне промиса, вы должны поймать его с помощью try/catch
:
try { getUserById('a') .then(user => console.log(user.username)) .catch(err => console.log(`Caught by .catch ${error}`)); } catch (error) { console.log(`Caught by try/catch ${error}`); }
Выход:
Caught by try/catch Error: Invalid id argument
Ошибки внутри промисов
Мы меняем getUserById()
, чтобы она выдавала ошибку внутри промиса:
let authorized = false; function getUserById(id) { return new Promise((resolve, reject) => { if (!authorized) { throw new Error('Unauthorized access to the user data'); } resolve({ id: id, username: 'admin' }); }); }
И обработаем промис:
try { getUserById(10) .then(user => console.log(user.username)) .catch(err => console.log(`Caught by .catch ${error}`)); } catch (error) { console.log(`Caught by try/catch ${error}`); }
Выход:
Caught by .catch Error: Unauthorized access to the user data
Если вы сгенерируете ошибку внутри промиса, ее поймает метод catch()
, а не try/catch.
Если вы связываете промисы, метод catch() будет ловить ошибки, возникающие в любом промисе. Например:
promise1 .then(promise2) .then(promise3) .then(promise4) .catch(err => console.log(err));
В этом примере, если в промисе1, промисе2 или промисе4 есть какая-либо ошибка, метод catch()
обработает ее.
Вызов функции reject()
Генерация ошибки имеет тот же эффект, что и вызов reject()
, как показано в следующем примере:
let authorized = false; function getUserById(id) { return new Promise((resolve, reject) => { if (!authorized) { reject('Unauthorized access to the user data'); } resolve({ id: id, username: 'admin' }); }); } try { getUserById(10) .then(user => console.log(user.username)) .catch(err => console.log(`Caught by .catch ${err}`)); } catch (error) { console.log(`Caught by try/catch ${error}`); }
В этом примере вместо того, чтобы генерировать ошибку внутри промиса, мы явно вызвали reject()
. В этом случае метод catch()
также обрабатывает ошибку.
Отсутствующий метод catch()
В следующем примере не используется метод catch()
для обработки ошибки внутри обещания. Это вызовет ошибку времени выполнения и завершит программу:
function getUserById(id) { return new Promise((resolve, reject) => { if (!authorized) { reject('Unauthorized access to the user data'); } resolve({ id: id, username: 'admin' }); }); } try { getUserById(10) .then(user => console.log(user.username)); // the following code will not execute console.log('next'); } catch (error) { console.log(`Caught by try/catch ${error}`); }
Выход:
Uncaught(in promise) Unauthorized access to the user data
Если обещание разрешено, вы можете опустить метод catch()
. В будущем потенциальная ошибка может привести к неожиданной остановке программы.
Заключение
- Внутри промиса метод
catch()
перехватит ошибку, вызванную операторомthrow
иreject()
. - Если возникает ошибка, а у вас нет метода
catch()
, механизм JavaScript выдает ошибку времени выполнения и останавливает программу.