news 2026/7/14 14:14:07

手写 ES6 Promise() 相关函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手写 ES6 Promise() 相关函数

手写 Promise() 相关函数:

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

// 定义三种状态常量constPENDING='pending'constFULFILLED='fulfilled'constREJECTED='rejected'classMyPromise{/* 定义状态和结果两个私有属性: 1.使用 # 语法(ES2022+ 官方私有字段):在类中通过 # 前缀声明属性,该属性仅在类的内部可访问 2.Symbol 作为属性键:用 Symbol 作为属性名,外部无法直接获取 Symbol 引用。 */#state=PENDING// 状态#result=undefined// 结果#thenables=[]// 存储 then 方法回调的队列constructor(executor){// resolve 和 reject 主要功能即为改变状态,设置结果constresolve=(value)=>{// 解决时调用this.#changeState(FULFILLED,value)}constreject=(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(typeofcallback!=='function'){// 状态穿透,即 then 方法返回的 Promise 状态与当前 Promise 状态保持一致// then 回调是微任务,需要放到微任务队列中执行queueMicrotask(()=>{// 参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/queueMicrotaskconstsettled=this.#state===FULFILLED?resolve:rejectsettled(this.#result)})return}queueMicrotask(()=>{try{constresult=callback(this.#result)// 如果返回值是一个 Promise,则等待它完成后再 resolveif(resultinstanceofMyPromise){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){returnnewMyPromise((resolve,reject)=>{// 将四个回调函数放入队列,以便立即或将来处理this.#thenables.push({onFulfilled,onRejected,resolve,reject})// 启动队列处理this.#run()})}catch(onRejected){returnthis.then(undefined,onRejected)}finally(onFinally){this.then((value)=>{MyPromise.resolve(onFinally()).then(()=>value)},(reason)=>{MyPromise.resolve(onFinally()).then(()=>{throwreason})})}}

验证测试 MyPromise() 函数

constp1=newPromise((resolve,reject)=>{resolve(1)reject(2)})console.log('p1',p1)constp2=newPromise(()=>{throw123})console.log('p2',p2)constp3=newPromise((resolve,reject)=>{setTimeout(()=>{resolve('setTimeout')// 无法捕获},0)})console.log('p3',p3)constmyP1=newMyPromise((resolve,reject)=>{resolve(1)reject(2)})console.log('myP1',myP1)myP1.then((res)=>{console.log('res',res)// 1returnres+1},(err)=>{console.log('err',err)// 1}).then((res)=>{console.log('res',res)// 2// throw 'error'returnres+1}).then((res)=>{console.log('res',res)// 3}).catch((err)=>{console.log('err',err)}).finally(()=>{console.log('finally')})constmyP2=newMyPromise(()=>{throw123})console.log('myP2',myP2)constmyP3=newMyPromise((resolve,reject)=>{setTimeout(()=>{resolve('setTimeout')// 无法捕获},0)})console.log('myP3',myP3)

执行结果

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 14:13:33

MTK安全启动分析7:MTK的preloader切换到tee的ATF原理

jumparch64 切换进入 ATF(BL31)完整原理前置架构基础Preloader 运行环境:AArch32(ARM32)、EL1 非安全世界(Normal World)ATF BL31 运行环境:AArch64(ARM64)、…

作者头像 李华
网站建设 2026/7/14 14:13:29

Keras-MMoE部署实战:将多任务模型集成到生产环境的完整指南

Keras-MMoE部署实战:将多任务模型集成到生产环境的完整指南 【免费下载链接】keras-mmoe A TensorFlow Keras implementation of "Modeling Task Relationships in Multi-task Learning with Multi-gate Mixture-of-Experts" (KDD 2018) 项目地址: http…

作者头像 李华
网站建设 2026/7/14 14:12:54

在线STL模型分割:从大型雕塑到精密零件的打印救星

1. 当3D打印机遇上"大块头":为什么我们需要分割STL模型?每次看到朋友家那台桌面级3D打印机,我就想起去年帮美术系学生打印毕业作品的经历。他们设计的1.5米高雕塑模型,在切片软件里显示需要连续打印72小时——这还没考虑…

作者头像 李华
网站建设 2026/7/14 14:11:42

PCF8591与TM4C129ENCPDT的ADC/DAC信号采集方案解析

1. 项目背景与硬件选型解析 当我们需要同时处理多个模拟信号时,如何选择合适的ADC/DAC转换方案成为嵌入式系统设计的关键问题。PCF8591和TM4C129ENCPDT这对组合恰好能解决这个痛点——前者是经典的8位ADC/DAC转换芯片,后者则是德州仪器(TI)推出的高性能A…

作者头像 李华
网站建设 2026/7/14 14:11:20

3步掌握黑苹果安装:OpenCore配置完整指南

3步掌握黑苹果安装:OpenCore配置完整指南 【免费下载链接】Hackintosh 国光的黑苹果安装教程:手把手教你配置 OpenCore 项目地址: https://gitcode.com/gh_mirrors/hac/Hackintosh 你是否想在普通PC上体验macOS的流畅操作和优雅界面?黑…

作者头像 李华
网站建设 2026/7/14 14:09:37

146、超分模型中的注意力机制对比:通道注意力、空间注意力与自注意力

146、超分模型中的注意力机制对比:通道注意力、空间注意力与自注意力 上个月调试一个轻量级超分模型,在Set5上PSNR死活卡在32.1dB上不去。我盯着loss曲线看了半天,发现模型对高频纹理区域完全“无动于衷”——天空平滑得像塑料,但草地细节却糊成一团。直觉告诉我,网络没有…

作者头像 李华