一共八步,带你实现 Promise

第一步 : 实现Promise的雏形

        class Commitment {
            static PENDING = '待定'
            static FULFILLED = '成功'
            static REJECTED = '拒绝'
            
            constructor(func) {
                this.status = Commitment.PENDING
                this.result = null
                func(this.resolve,this.reject)
            }

            resolve(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.FULFILLED
                    this.result = result
                }
            }

            reject(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.REJECTED
                    this.result = result
                }
            }
        }   
        */

存在问题:

  1. error : 找不到 status,原因在于在 resolve 方法中,我们在 constructor外面使用了 this.status 。
  2. 这里的 this 并没有指向 promise 实例,而是指向了构造函数的原型对象,因此我们要给 resolve 和 reject 绑定 this 。

第二步 : 绑定 this,让 resolve 和 reject 方法中的 this 恒为 promise 实例

		class Commitment {
            static PENDING = '待定'
            static FULFILLED = '成功'
            static REJECTED = '拒绝'
            
            constructor(func) {
                this.status = Commitment.PENDING
                this.result = null
                func(this.resolve.bind(this),this.reject.bind(this))
            }

            resolve(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.FULFILLED
                    this.result = result
                }
            }

            reject(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.REJECTED
                    this.result = result
                }
            }
        }

第三步 : 实现then方法

 		class Commitment {
            static PENDING = '待定'
            static FULFILLED = '成功'
            static REJECTED = '拒绝'
            
            constructor(func) {
                this.status = Commitment.PENDING
                this.result = null
                func(this.resolve.bind(this),this.reject.bind(this))
            }

            resolve(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.FULFILLED
                    this.result = result
                }
            }

            reject(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.REJECTED
                    this.result = result
                }
            }

            then(onFulfilled,onReject){
                if(this.status === Commitment.FULFILLED) {
                    onFulfilled(this.result)
                }

                if(this.status === Commitment.REJECTED) {
                    onReject(this.result)
                }
            }
        }

        let p = new Commitment((resolve,reject) => {
            resolve('123')
        })

        console.log(p)

第四步 : try catch 捕获错误

         class Commitment {
            static PENDING = '待定'
            static FULFILLED = '成功'
            static REJECTED = '拒绝'
            
            constructor(func) {
                this.status = Commitment.PENDING
                this.result = null
                try {
                    func(this.resolve.bind(this),this.reject.bind(this))
                } catch (error) {
                    this.reject(error)
                }
                
            }

            resolve(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.FULFILLED
                    this.result = result
                }
            }

            reject(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.REJECTED
                    this.result = result
                }
            }

            then(onFulfilled,onReject){
                if(this.status === Commitment.FULFILLED) {
                    onFulfilled(this.result)
                }

                if(this.status === Commitment.REJECTED) {
                    onReject(this.result)
                }
            }
        }

第五步,then的两个参数未必都传入函数,解决传入其他数据类型数据报错的问题

		class Commitment {
            static PENDING = '待定'
            static FULFILLED = '成功'
            static REJECTED = '拒绝'
            
            constructor(func) {
                this.status = Commitment.PENDING
                this.result = null
                try {
                    func(this.resolve.bind(this),this.reject.bind(this))
                } catch (error) {
                    this.reject(error)
                }
                
            }

            resolve(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.FULFILLED
                    this.result = result
                }
            }

            reject(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.REJECTED
                    this.result = result
                }
            }

            then(onFulfilled,onReject){
                onFsulfilled = typeof onFulfilled === "function" ? onFulfilled : () => {}
                onReject = typeof onReject === "function" ? onReject : () => {}

                if(this.status === Commitment.FULFILLED) {
                    onFulfilled(this.result)
                }

                if(this.status === Commitment.REJECTED) {
                    onReject(this.rsesult)
                }
            }
        }

        let p = new Commitment((resolve,reject) => {
            resolve('123')
        })

        console.log(p)

第六步,Promise 是如何实现异步的,通过定时器setTimeout

注意:promise 本身属于同步任务,then、catch、finaly 属于异步任务

		class Commitment {
            static PENDING = '待定'
            static FULFILLED = '成功'
            static REJECTED = '拒绝'
            
            constructor(func) {
                this.status = Commitment.PENDING
                this.result = null
                try {
                    func(this.resolve.bind(this),this.reject.bind(this))
                } catch (error) {
                    this.reject(error)
                }
                
            }

            resolve(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.FULFILLED
                    this.result = result
                }
            }

            reject(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.REJECTED
                    this.result = result
                }
            }

            then(onFulfilled,onReject){
                onFsulfilled = typeof onFulfilled === "function" ? onFulfilled : () => {}
                onReject = typeof onReject === "function" ? onReject : () => {}

                if(this.status === Commitment.FULFILLED) {
                    setTimeout(() => {
                        onFulfilled(this.result)
                    })
                }

                if(this.status === Commitment.REJECTED) {
                    setTimeout(() => {
                        onReject(this.rsesult)
                    })
                    
                }
            }
        }

第七步: 实现 resolve 之前无法执行 then

具体的实现为:

  1. 创建this.resolveCallbacks=[]保存resolve的执行结果
  2. 创建this.rejectCallbacks=[]保存reject的执行结果
  3. 在then里,判断当前状态为待定时,将对应的函数onFULFILLED,onREJECT都push到对应数组中
    之后在resolve和reject里遍历数组
  4. 这里还有一个坑,resolve和reject在事件循环末尾执行,所以要在resolve和reject里加上setTimeout
 		class Commitment {
            static PENDING = '待定' 
            static FULFILLED = '成功'
            static REJECTED = '拒绝'
            
            constructor(func) {
                this.status = Commitment.PENDING
                this.result = null
                this.resolveCallbacks = []
                this.rejectCallbacks = []
                try {
                    func(this.resolve.bind(this),this.reject.bind(this))
                } catch (error) {
                    this.reject(error)
                }
                
            }

            resolve(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.FULFILLED
                    this.result = result
                    this.resolveCallbacks.forEach((cb) => {
                        cb(result)
                    })
                }
            }

            reject(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.REJECTED
                    this.result = result
                    this.rejectCallbacks.forEach((cb) => {
                        cb(result)
                    })
                }
            }

            then(onFulfilled,onReject){
                onFsulfilled = typeof onFulfilled === "function" ? onFulfilled : () => {}
                onReject = typeof onReject === "function" ? onReject : () => {}

                if(this.status === Commitment.PENDING) {
                    this.resolveCallbacks.push(onFulfilled)
                    this.rejectCallbacks.push(onReject)
                }

                if(this.status === Commitment.FULFILLED) {
                    setTimeout(() => {
                        onFulfilled(this.result)
                    })
                }

                if(this.status === Commitment.REJECTED) {
                    setTimeout(() => {
                        onReject(this.rsesult)
                    })
                    
                }
            }
        }

第八步,实现链式调用,将then中的逻辑重新包裹为一个Commitment实例并返回即可

		class Commitment {
            static PENDING = '待定' 
            static FULFILLED = '成功'
            static REJECTED = '拒绝'
            
            constructor(func) {
                this.status = Commitment.PENDING
                this.result = null
                this.resolveCallbacks = []
                this.rejectCallbacks = []
                try {
                    func(this.resolve.bind(this),this.reject.bind(this))
                } catch (error) {
                    this.reject(error)
                }
                
            }

            resolve(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.FULFILLED
                    this.result = result
                    this.resolveCallbacks.forEach((cb) => {
                        cb(result)
                    })
                }
            }

            reject(result){
                if(this.status === Commitment.PENDING) {
                    this.status = Commitment.REJECTED
                    this.result = result
                    this.rejectCallbacks.forEach((cb) => {
                        cb(result)
                    })
                }
            }

            then(onFulfilled,onReject){

                return new Commitment((resovle,reject) => {
                    onFsulfilled = typeof onFulfilled === "function" ? onFulfilled : () => {}
                    onReject = typeof onReject === "function" ? onReject : () => {}

                    if(this.status === Commitment.PENDING) {
                        this.resolveCallbacks.push(onFulfilled)
                        this.rejectCallbacks.push(onReject)
                    }

                    if(this.status === Commitment.FULFILLED) {
                        setTimeout(() => {
                            onFulfilled(this.result)
                        })
                    }

                    if(this.status === Commitment.REJECTED) {
                        setTimeout(() => {
                            onReject(this.rsesult)
                        })
                        
                    }
                })
            }
        }

验证:

		
		console.log('1')

        let promise = new Commitment((resolve,reject)=>{
            console.log('2')
            setTimeout(()=>{
                resolve('5')
                console.log('4')
            })
        })
        promise.then(
            result =>{
            console.log('执行')
                
                console.log(result)}
        )
        console.log('3')

        // 输出结果为 12345
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WongLeer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值