Promise 错误处理

概要: 在本教程中,您将学习如何在 Promise 中处理错误。

假设您有一个名为 getUserById() 的函数,它返回一个 Promise

function getUserById(id) {
    return new Promise((resolve, reject) => {
        resolve({
            id: id,
            username: 'admin'
        });
    });
}Code language: JavaScript (javascript)

普通错误

首先,将 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'
        });
    });
}Code language: JavaScript (javascript)

其次,使用 then()catch() 方法处理 Promise

getUserById('a')
    .then(user => console.log(user.username))
    .catch(err => console.log(err));Code language: JavaScript (javascript)

代码抛出错误

Uncaught Error: Invalid id argumentCode language: JavaScript (javascript)

当您在 Promise 外部引发异常时,您必须使用 try/catch 捕获它

try {
    getUserById('a')
        .then(user => console.log(user.username))
        .catch(err => console.log(`Caught by .catch ${err}`));
} catch (error) {
    console.log(`Caught by try/catch ${error}`);
}Code language: JavaScript (javascript)

输出

Caught by try/catch Error: Invalid id argumentCode language: JavaScript (javascript)

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'
        });
    });
}Code language: JavaScript (javascript)

并使用 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}`);
}Code language: JavaScript (javascript)

输出

Caught by .catch Error: Unauthorized access to the user dataCode language: JavaScript (javascript)

如果您在 Promise 内部抛出错误,catch() 方法会捕获它,而不是 try/catch。

如果您链接 Promise,catch() 方法将捕获任何 Promise 中发生的错误。例如

promise1
    .then(promise2)
    .then(promise3)
    .then(promise4)
    .catch(err => console.log(err));
Code language: JavaScript (javascript)

在此示例中,如果 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}`);
}
Code language: JavaScript (javascript)

在此示例中,我们没有在 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}`);
}Code language: JavaScript (javascript)

输出

Uncaught (in promise) Unauthorized access to the user data

如果 Promise 已解决,则可以省略 catch() 方法。将来,潜在的错误可能会导致程序意外停止。

总结

  • 在 Promise 内部,catch() 方法将捕获由 throw 语句和 reject() 引起的错误。
  • 如果发生错误,并且您没有 catch() 方法,JavaScript 引擎将发出运行时错误并停止程序。
本教程对您有帮助吗?