В этом руководстве вы узнаете, как работать с обработкой ошибок в промисах в 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 выдает ошибку времени выполнения и останавливает программу.
