在本教程中,您将学习如何处理 promise 的错误处理。假设你有一个函数 getUserById()
返回 Promise:
function getUserById(id) {
return new Promise((resolve, reject) => {
resolve({
id: id,
username: 'admin'
});
});
}
普通错误
首先,修改 getUserById()
函数以在 promise 外部抛出错误:
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()
方法消费 Promise:
getUserById('a')
.then(user => console.log(user.username))
.catch(err => console.log(err));
代码将抛出错误:
Caught by try/catch Error: Invalid id argument
当您在 Promise 之外引发异常时,您必须使用 try/catch
方法捕获它:
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'
});
});
}
输出:
Caught by try/catch Error: Invalid id argument
Promise 的错误
我们修改 getUserById()
函数在 promise 抛出错误:
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'
});
});
}
并消费 promise:
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}`);
}
输出:
Caught by .catch Error: Unauthorized access to the user data
如果您在 promise 抛出错误,catch()
方法将捕获它,而不是 try/catch
。如果你链式调用 promise,catch() 方法将捕获 promise 中发生的任何错误。例如:
promise1
.then(promise2)
.then(promise3)
.then(promise4)
.catch(err => console.log(err));
在此示例中,如果 promise1、promise2 或 promise4 中有任何错误,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}`);
}
在这个例子中,我们没有在 promise 中抛出错误,而是reject()
显式地调用了。在这种情况下,该catch()
方法还会处理错误。
缺少 catch() 方法
下面的示例未提供 catch()
处理 promise 内部错误的方法。它将导致运行时错误并终止程序:
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
如果 promise 已解决,则可以省略 catch()
方法。将来,潜在的错误可能会导致程序意外停止。
结论
- 在 promise 内部,
catch()
方法将捕获由语句throw
和reject()
引起的错误。 - 如果发生错误并且您没有
catch()
方法,则 JavaScript 引擎会抛出运行时错误并停止程序。