实现 promise.finally

Promise.prototype.finally() 方法返回一个Promise。它在Promise被解决(无论是fulfilled还是rejected)后都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方便的方式。finally并不会改变Promise的结果值,而是返回原Promise或者一个新的Promise。

实现Promise.prototype.finally

要实现finally方法,我们需要考虑以下几点:1. finally回调不接受任何参数,因为它的目的是在Promise完成后执行一些清理工作,而不关心Promise的结果。2. finally应该返回一个Promise,这个Promise的解决状态和原Promise相同。3. 如果finally回调中返回了一个Promise,那么外部链上的后续Promise应该等待这个Promise也完成后才继续执行。基于以上考虑,我们可以这样实现Promise.prototype.finally:

js 复制代码
Promise.prototype.finally = function(callback) {
  // `this` 指向当前Promise实例
  return this.then(
    // Promise成功时执行的函数
    value => Promise.resolve(callback()).then(() => value),
    // Promise失败时执行的函数
    reason => Promise.resolve(callback()).then(() => { throw reason; })
  );
};

解释

  • this.then(...):我们通过调用.then方法来确保无论原Promise是fulfilled还是rejected,callback都会被执行。

  • value => Promise.resolve(callback()).then(() => value):如果原Promise成功,我们首先执行callback,并确保callback的返回值(如果有的话)被Promise.resolve包装,这样即使callback返回了一个Promise,它也会被正确处理。之后,我们通过.then(() => value)确保返回一个新的Promise,这个Promise解决为原Promise的值。

  • reason => Promise.resolve(callback()).then(() => { throw reason; }):如果原Promise失败,处理方式类似,不同之处在于我们需要通过throw reason来确保返回的Promise被拒绝,并且拒绝的原因与原Promise相同。

js 复制代码
let promise = new Promise((resolve, reject) => {
  setTimeout(() => resolve("result"), 1000);
});

promise
  .then(result => console.log(result))
  .finally(() => console.log("Promise completed"))
  .then(() => console.log("Chain continued"));

在这个示例中,无论promise是成功还是失败,"Promise completed"都会被打印出来。而且,由于finally不改变Promise的结果,所以"Chain continued"也会在finally之后被打印。通过这种方式,finally提供了一种无论Promise结果如何都需要执行某些操作的简洁方法,这在进行资源清理等操作时特别有用。

相关推荐
火车叼位1 分钟前
Volta 下 `corepack` 失踪之谜:问题不在 Node,而在命令入口
前端
cmd4 分钟前
别再用错!5种JS类型判断方法,从原理到实战一文吃透
前端·javascript
小江的记录本8 分钟前
【Redis】Redis常用命令速查表(完整版)
java·前端·数据库·redis·后端·spring·缓存
Csvn12 分钟前
状态管理方案对比(Context、Zustand、Jotai 选型指南)
前端
snow_yan13 分钟前
基于 json-render 的流式表单渲染方案
前端·react.js·llm
wobi_baoyan15 分钟前
【已解决】使用Maven打包发生或者启动Spring Boot项目发生 错误: 不支持发行版本 17
服务器·前端·javascript
Dylan~~~15 分钟前
Go语言Web框架选型指南:从入门到精通
开发语言·前端·golang
学以智用17 分钟前
# TypeScript 高级特性(核心+实用)
前端·javascript·typescript
学以智用18 分钟前
TypeScript 核心基础:类型/变量 + 函数 + 接口
前端·javascript·typescript
SuperEugene21 分钟前
Vue3 组件解耦实战:Props/Emit/ 事件总线用法 + 避坑指南|Vue 组件与模板规范篇
前端·javascript·vue.js