手写Promise里面then方法的优化
1:then的多次调用---then方法保存在数组里面,调用resolve的时候遍历数组
1 // then的多次调用 then方法都保存在数组里,然后调用resolve的时候遍历数组就好啦 2 //定时器里面的then不会执行 利用状态判断更严谨 3 const PEOMISE_STATUS_PENDING = 'pending' 4 const PEOMISE_STATUS_FULFILLED = 'fulfilled' 5 const PEOMISE_STATUS_REJECTED = 'rejected' 6 class tyyPromise { 7 constructor(executor) { 8 this.status = PEOMISE_STATUS_PENDING 9 this.value = undefined 10 this.reason = undefined 11 this.onFulfilledfns = [] 12 this.onRejectedfns = [] 13 const resolve = (value) => { 14 if (this.status === PEOMISE_STATUS_PENDING) { 15 //添加微任务 16 queueMicrotask(() => { 17 if (this.status !== PEOMISE_STATUS_PENDING) return 18 this.status = PEOMISE_STATUS_FULFILLED 19 this.value = value 20 this.onFulfilledfns.forEach((onFulfilled) => { 21 onFulfilled(this.value) 22 }) 23 }) 24 } 25 26 27 } 28 const reject = (reason) => { 29 if (this.status === PEOMISE_STATUS_PENDING) { 30 31 //以免then还没执行 32 queueMicrotask(() => { 33 if (this.status !== PEOMISE_STATUS_PENDING) return 34 this.status = PEOMISE_STATUS_REJECTED 35 this.reason = reason 36 this.onRejectedfns.forEach((onRejected) => { 37 onRejected(this.reason) 38 }) 39 }) 40 } 41 } 42 43 executor(resolve, reject) 44 } 45 then(onFulfilled, onRejected) { 46 //判断状态解决定时器里面的then执行不了的问题 47 if (this.status === PEOMISE_STATUS_FULFILLED && onFulfilled) 48 onFulfilled(this.value) 49 //把then的回调放到数组里面去 50 if (this.status === PEOMISE_STATUS_REJECTED && onRejected) 51 onRejected(this.reason) 52 if (this.status === PEOMISE_STATUS_PENDING) { 53 this.onFulfilledfns.push(onFulfilled) 54 this.onRejectedfns.push(onRejected) 55 } 56 57 } 58 } 59 const promise = new tyyPromise((resolve, reject) => { 60 // console.log('pending'); 61 reject(111) 62 resolve(222) 63 64 }) 65 promise.then(res => { 66 console.log('res1:', res); 67 }, err => { 68 console.log('err1:', err); 69 }) 70 promise.then(res => { 71 console.log('res2:', res); 72 }, err => { 73 console.log('err2:', err); 74 }) 75 setTimeout(() => { 76 promise.then(res => { 77 console.log('res3:', res); 78 }, err => { 79 console.log('err3:', err); 80 }) 81 }, 1000)
2:让then链式调用----在then方法里面return一个新的Promise 再调用resolve(同时利用try catch方便捕获到异常)resolve的参数是调用之后的结果
//return 一个 利用try catch来捕获异常 //链式调用的相关优化 //代码重复量比较大时,可以封装工具函数 const PEOMISE_STATUS_PENDING = 'pending' const PEOMISE_STATUS_FULFILLED = 'fulfilled' const PEOMISE_STATUS_REJECTED = 'rejected' //封装函数 function exeFunction(exefunction, value, resolve, reject) { try { const result = exefunction(value) resolve(result) } catch (err) { reject(err) } } class tyyPromise { constructor(executor) { this.status = PEOMISE_STATUS_PENDING this.value = undefined this.reason = undefined this.onFulfilledfns = [] this.onRejectedfns = [] const resolve = (value) => { if (this.status === PEOMISE_STATUS_PENDING) { //添加微任务 queueMicrotask(() => { if (this.status !== PEOMISE_STATUS_PENDING) return this.status = PEOMISE_STATUS_FULFILLED this.value = value this.onFulfilledfns.forEach((onFulfilled) => { onFulfilled(this.value) }) }) } } const reject = (reason) => { if (this.status === PEOMISE_STATUS_PENDING) { //以免then还没执行 queueMicrotask(() => { if (this.status !== PEOMISE_STATUS_PENDING) return this.status = PEOMISE_STATUS_REJECTED this.reason = reason this.onRejectedfns.forEach((onRejected) => { onRejected(this.reason) }) }) } } try { executor(resolve, reject) } catch (err) { reject(err); } } then(onFulfilled, onRejected) { //直接给它返回 因为executor会直接执行的 return new tyyPromise((resolve, reject) => { //判断状态解决定时器里面的then执行不了的问题 if (this.status === PEOMISE_STATUS_FULFILLED && onFulfilled) { //实现链式调用 // try { // const result = onFulfilled(this.value) // resolve(result) // } catch (err) { // reject(err); // } exeFunction(onFulfilled, this.value, resolve, reject) } //把then的回调放到数组里面去 if (this.status === PEOMISE_STATUS_REJECTED && onRejected) { // try { // const result = onRejected(this.reason) // resolve(result) // } catch (err) { // reject(err); // } exeFunction(onRejected, this.reason, resolve, reject) } if (this.status === PEOMISE_STATUS_PENDING) { this.onFulfilledfns.push(() => { // try { // const result = onFulfilled(this.value) // resolve(result) // } catch (err) { // reject(err); // } exeFunction(onFulfilled, this.value, resolve, reject) }) this.onRejectedfns.push(() => { // try { // const result = onRejected(this.reason) // resolve(result) // } catch (err) { // reject(err); // } exeFunction(onRejected, this.reason, resolve, reject) }) } }) } } const promise = new tyyPromise((resolve, reject) => { // console.log('pending'); // reject(111) resolve(222) // throw new Error("抛出的异常error") }) promise.then(res => { console.log('res1:', res); // return 'aaaa' throw new Error("抛出的异常error") }, err => { console.log('err1:', err); // throw new Error("抛出的异常error") }).then(res => { console.log('res2:', res); }, err => { console.log('err2', err); })
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!