当前位置: 首页 > article >正文

手写ES6 Promise() 相关函数

手写 Promise() 相关函数:

Promise()、then()、catch()、finally()

// 定义三种状态常量
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'class MyPromise {/*定义状态和结果两个私有属性:1.使用 # 语法(ES2022+ 官方私有字段):在类中通过 # 前缀声明属性,该属性仅在类的内部可访问2.Symbol 作为属性键:用 Symbol 作为属性名,外部无法直接获取 Symbol 引用。*/#state = PENDING // 状态#result = undefined // 结果#thenables = [] // 存储 then 方法回调的队列constructor(executor) {// resolve 和 reject 主要功能即为改变状态,设置结果const resolve = (value) => { // 解决时调用this.#changeState(FULFILLED, value)}const reject = (reason) => { // 拒绝时调用this.#changeState(REJECTED, reason)}try { // 只能捕获同步错误,无法捕获异步错误,如 setTimeout 里的错误executor(resolve, reject)} catch (err) {reject(err)}}// 改变状态和设置结果的私有方法#changeState(state, result) {if (this.#state !== PENDING) returnthis.#state = statethis.#result = resultthis.#run()}// 处理 then 回调的私有方法#handleCallback(callback, resolve, reject) {if (typeof callback !== 'function') { // 状态穿透,即 then 方法返回的 Promise 状态与当前 Promise 状态保持一致// then 回调是微任务,需要放到微任务队列中执行queueMicrotask(() => { // 参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/queueMicrotaskconst settled = this.#state === FULFILLED ? resolve : rejectsettled(this.#result)})return}queueMicrotask(() => {try {const result = callback(this.#result)// 如果返回值是一个 Promise,则等待它完成后再 resolveif (result instanceof MyPromise) {result.then(resolve, reject)} else {resolve(result)}} catch (err) {reject(err)}})}/*执行队列的私有方法,两个执行时机:1.Promise 状态改变时2.then 方法被调用时*/#run() {if (this.#state === PENDING) return// 取出队列中的回调函数,依次执行(先进先出原则)while (this.#thenables.length) {const { onFulfilled, onRejected, resolve, reject } = this.#thenables.shift()try {if (this.#state === FULFILLED) { // 执行 onFulfilled 回调函数this.#handleCallback(onFulfilled, resolve, reject)} else { // 执行 onRejected 回调函数this.#handleCallback(onRejected, resolve, reject)}} catch (err) {reject(err)}}}/*onFulfilled 可选:一个在此 Promise 对象被兑现时异步执行的函数。它的返回值将成为 then() 返回的 Promise 对象的兑现值。onRejected 可选:一个在此 Promise 对象被拒绝时异步执行的函数。它的返回值将成为 catch() 返回的 Promise 对象的兑现值。*/then(onFulfilled, onRejected) {return new MyPromise((resolve, reject) => {// 将四个回调函数放入队列,以便立即或将来处理this.#thenables.push({onFulfilled,onRejected,resolve,reject})// 启动队列处理this.#run()})}catch(onRejected) {return this.then(undefined, onRejected)}finally(onFinally) {this.then((value) => {MyPromise.resolve(onFinally()).then(() => value)},(reason) => {MyPromise.resolve(onFinally()).then(() => { throw reason })})}
}

验证测试 MyPromise() 函数

const p1 = new Promise((resolve, reject) => {resolve(1)reject(2)
})
console.log('p1', p1)
const p2 = new Promise(() => { throw 123 })
console.log('p2', p2)
const p3 = new Promise((resolve, reject) => {setTimeout(() => {resolve('setTimeout') // 无法捕获}, 0)
})
console.log('p3', p3)
const myP1 = new MyPromise((resolve, reject) => {resolve(1)reject(2)
})
console.log('myP1', myP1)
myP1.then((res) => {console.log('res', res) // 1return res + 1},(err) => {console.log('err', err) // 1}
).then((res) => {console.log('res', res) // 2// throw 'error'return res + 1
}).then((res) => {console.log('res', res) // 3
}).catch((err) => {console.log('err', err)
}).finally(() => {console.log('finally')
})
const myP2 = new MyPromise(() => { throw 123 })
console.log('myP2', myP2)
const myP3 = new MyPromise((resolve, reject) => {setTimeout(() => {resolve('setTimeout') // 无法捕获}, 0)
})
console.log('myP3', myP3)

执行结果

在这里插入图片描述

http://www.lryc.cn/news/2385270.html

相关文章:

  • Windows 平台 TCP 通信开发指南
  • 【NLP 76、Faiss 向量数据库】
  • 软件名称:系统日志监听工具 v1.0
  • Spring AI 之结构化输出转换器
  • Java虚拟机面试题:内存管理(上)
  • 进程间通信I·匿名管道
  • Ubuntu Linux系统的基本命令详情
  • 大数据治理:理论、实践与未来展望(二)
  • PCB布局设计
  • 【49. 字母异位词分组】
  • 用 AI 让学习更懂你:如何打造自动化个性化学习系统?
  • esp32+IDF V5.1.1版本编译freertos报错
  • 嵌入式软件-如何做好一份技术文档?
  • 笔记本6GB本地可跑的图生视频项目(FramePack)
  • SpringMVC实战:动态时钟
  • vscode include总是报错
  • 哈希表的实现(上)
  • 【Java高阶面经:微服务篇】1.微服务架构核心:服务注册与发现之AP vs CP选型全攻略
  • 实验7 HTTP协议分析与测量
  • python:机器学习概述
  • 【一. Java基础:注释、变量与数据类型详解】
  • 得力DE-620K针式打印机打印速度不能调节维修一例
  • SAP在金属行业的数字化转型:无锡哲讯科技的智能解决方案
  • 安装openresty使用nginx+lua,openresty使用jwt解密
  • java基础(继承)
  • python 实现一个完整的基于Python的多视角三维重建系统,包含特征提取与匹配、相机位姿估计、三维重建、优化和可视化等功能
  • 行列式中某一行的元素与另一行对应元素的代数余子式乘积之和等于零
  • 【时时三省】Python 语言----字符串,列表,元组,字典常用操作异同点
  • 基于cornerstone3D的dicom影像浏览器 第二十二章 mpr + vr
  • 优启通添加自定义浏览器及EXLOAD使用技巧分享