在本教程中,您将学习如何使用 JavaScript Promise finally() 方法在 Promise 确定后执行代码,而不管其结果如何。

JavaScript Promise finally() 方法介绍

假设你有一个 Promise

promise
    .then(result => { ...})
    .catch(error => { ... })
    .finally(() => { ... })

无论 promise 是被解决还是被拒绝,finally() 方法总是被执行。换句话说,finally() 方法是 promise 最后执行的方法。

finally()方法在 ES2018 引入。在 finally() 方法中,您可以在 promise 最后编写清理资源的代码,而不管其结果如何。

通过使用 finally() 方法,您可以避免像这样 then()catch() 方法中的重复代码:

promise
    .then(result => {
        // 处理结果
        // 清理某些资源
    })
    .catch(error => {
        // 处理错误
        // 清理某些资源
    });

现在,您可以将清理资源部分的代码移动到 finally() 方法,如下所示:

promise
    .then(result => {
        // 处理结果
    })
    .catch(error => {
        // 处理错误
    })
    .finally(() => {
        // 清理某些资源
    });

finally() 方法类似于 try...catch...finally 语句的 finally 。在同步代码中,您使用 finally 来清理资源。在异步代码中,您将改用 finally() 方法。

JavaScript Promise finally() 方法示例

下面定义一个 Connection 类:

class Connection {
    execute(query) {
        if (query != 'Insert' && query != 'Update' && query != 'Delete') {
            throw new Error(`The ${query} is not supported`);
        }
        console.log(`Execute the ${query}`);
        return this;
    }
    close() {
        console.log('Close the connection')
    }
}

Connection 类有两个方法: execute()close()

  • execute() 方法将只执行插入、更新或删除查询。如果您传递到另一个不在列表中的查询,它将抛出错误。
  • close() 方法关闭连接,清理资源。

如果 success 变量设置为 true,下面 connect() 的函数将返回解析为 Connection 的 Promise:

const success = true;

function connect() {
    return new Promise((resolve, reject) => {
        if (success)
            resolve(new Connection());
        else
            reject('Could not open the database connection');
    });
}

下面的示例使用 finally() 方法关闭连接:

let globalConnection;

connect()
    .then((connection) => {
        globalConnection = connection;
        return globalConnection.execute('Insert');
    })
    .then((connection) => {
        globalConnection = connection;
        return connection.execute('Select');
    })
    .catch(console.log)
    .finally(() => {
        if (globalConnection) {
            globalConnection.`close()`;
        }
    });

在这个例子中:

  • connect() 函数解析为一个 Connection  对象,因为 success 变量设置为true
  • 第一个 then() 方法执行 Insert 查询并返回一个 Connection 对象。globalConnection 用于保存连接。
  • 第二个 then() 方法执行 Select 查询并抛出错误。catch() 方法打印错误消息,finally() 方法关闭连接。

结论

  • finally() 方法增加一个函数在 Promise 被解决时执行,无论是 Promise 解决还是拒绝。
  • 一个很好的做法是,一旦 promise 得到解决,就将清理资源的代码放在 finally() 方法,而不管其结果如何。