Promise.prototype.finally()

finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

  1. promise
  2. .then(result => {···})
  3. .catch(error => {···})
  4. .finally(() => {···});

上面代码中,不管promise最后的状态,在执行完thencatch指定的回调函数以后,都会执行finally方法指定的回调函数。

下面是一个例子,服务器使用 Promise 处理请求,然后使用finally方法关掉服务器。

  1. server.listen(port)
  2. .then(function () {
  3. // ...
  4. })
  5. .finally(server.stop);

finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。

finally本质上是then方法的特例。

  1. promise
  2. .finally(() => {
  3. // 语句
  4. });
  5. // 等同于
  6. promise
  7. .then(
  8. result => {
  9. // 语句
  10. return result;
  11. },
  12. error => {
  13. // 语句
  14. throw error;
  15. }
  16. );

上面代码中,如果不使用finally方法,同样的语句需要为成功和失败两种情况各写一次。有了finally方法,则只需要写一次。

它的实现也很简单。

  1. Promise.prototype.finally = function (callback) {
  2. let P = this.constructor;
  3. return this.then(
  4. value => P.resolve(callback()).then(() => value),
  5. reason => P.resolve(callback()).then(() => { throw reason })
  6. );
  7. };

上面代码中,不管前面的 Promise 是fulfilled还是rejected,都会执行回调函数callback

从上面的实现还可以看到,finally方法总是会返回原来的值。

  1. // resolve 的值是 undefined
  2. Promise.resolve(2).then(() => {}, () => {})
  3. // resolve 的值是 2
  4. Promise.resolve(2).finally(() => {})
  5. // reject 的值是 undefined
  6. Promise.reject(3).then(() => {}, () => {})
  7. // reject 的值是 3
  8. Promise.reject(3).finally(() => {})