ES 提案:Promise.prototype.finally

ES 提案:Promise.prototype.finally

提案 “Promise.prototype.finally” 由 Jordan Harband 提出,这篇博客文章解释它。

怎样使用

.finally() 使用方法:

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

finally 的回调函数总会被执行。差别如下:

  • then 的回调函数仅会在 Promise 的状态是成功时(fulfilled)执行。
  • catch 的回调函数仅会在 Promise 的状态是失败时(rejected)执行。或者 then 的回调函数抛出一个异常或返回一个 rejected Promise。

其它方面:尝试下面的代码段。

promise
.finally(() => {
    «statements»
});

该代码段等价于:

promise
.then(
  result => {
    «statements»
    return result;
  },
  error => {
    «statements»
    throw error;
  }
);

用例

最常用的用例类似于异步 finally 子句:完成资源使用后进行清理。无论一切顺利还是出现错误,finally 都应该始终执行。举例来说:

let connection;
db.open()
  .then((conn) => {
    connection = conn;
    return connection.select({ name: 'Jane' });
  })
  .then((result) => {
    // Process result
    // Use `connection` to make more queries
  })
  .catch((error) => {
    // handle errors
  })
  .finally(() => {
    connection.close();
  });

.finally() 类似于同步代码中的 finally {}

在同步代码中,try 语句有三个部分:try 子句,catch 子句和 finally 子句。

在 Promise 中:

  • try 子句非常松散地对应 Promise 基础函数或 .then() 函数。
  • catch 子句对应 Promise 的 .catch() 方法。
  • finally 子句对应提案引进的 Promise 新方法 .finally()

然而,finally {} 可以 returnthrow 而在回调 .finally() 内部无效,仅抛出异常。这是因为该方法无法区分显式返回的回调和未完成的回调。

可用性

  • npm 包 promise.prototype.finally.finally() 的可用填充库。
  • V8 5.8+(如在 Node.js 8.1.4+):开启 flag 使之可用 --harmony-promise-finally(详情)

扩展阅读

本文作者 Axel Rauschmayer,转载请注明来源链接:

原文链接:https://2ality.com/2017/07/promise-prototype-finally.html

本文链接:https://tie.pub/2019/10/promise-prototype-finally/