手写Promise的实现

简易实现Promise的几个功能包含异步处理、回调处理、链式调用、异常捕获等基础功能。

原生Promise功能

	// 后面手写需要实现的功能
	let a = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(11)
            // reject(22)
        }, 200)
    })
    a.then((res) => {
        console.log(res);
        return '新的'
    }).then((res) => {
    	console.log(res);
        return Promise.reject('我错了')
    }).catch((res) => {
        console.log('error:', res);
    })
	// 以上代码输出内容:
	11
	新的
	error: 我错了

代码解析:给Promise的构造器传一个参数,这个参数是一个立即执行的回调函数,该回调函数就是Promise实现异步的核心。

手写实现上述Promise功能

定义一个包含构造函数的myPromise类,其中包含state和result两个字段,构造函数接收并执行一个函数参数fun,执行fun函数的时候将本身的resolve和reject处理函数传过去。resolve和reject需要使用箭头函数,不然会存在this指向问题。
state: 包含三种状态:pendding、success(最终态)、fail(最终态),分别代表异步执行等待中、异步执行成功、异步执行失败的状态。
result: 代表函数执行结束时传递的值。

	class myPromise {
        state = 'pendding'
        result = null
        constructor(fun) {
            this.state = 'pendding'
            this.result = null
            fun(this.resolve, this.reject)
        }
        resolve = (data) => {
            
        }
        reject = (data) => {
            
        }
    }

完善resolve和reject函数,将函数状态和函数结果参数进行赋值,由于Promise中状态不可逆,最终只能由pending变成完成态(success或fail),所以增加状态判断。

	class myPromise {
        state = 'pendding'
        result = null
        constructor(fun) {
            this.state = 'pendding'
            this.result = null
            fun(this.resolve, this.reject)
        }
        resolve = (data) => {
            if (this.state === 'pendding') {
                this.state = 'success'
                this.result = data
            }
        }
        reject = (data) => {
            if (this.state === 'pendding') {
                this.state = 'fail'
                this.result = data
            }
        }
    }

增加成功回调函数then和错误处理函数catch,用于处理异步操作。实现异步处理,还需增加两个参数successCallback,failCallback,由于在实例中调用时是同步操作,所以在状态未变成最终态时先使用参数将回调存储下来,等状态变化后再执行相应的回调函数。

	class myPromise {
        state = 'pendding'
        result = null
        successCallback = null
        failCallback = null
        constructor(fun) {
            this.state = 'pendding'
            this.result = null
            fun(this.resolve, this.reject)
        }
        resolve = (data) => {
            if (this.state === 'pendding') {
                this.state = 'success'
                this.result = data
                this.successCallback && this.successCallback(this.result)
            }
        }
        reject = (data) => {
            if (this.state === 'pendding') {
                this.state = 'fail'
                this.result = data
                this.failCallback && this.failCallback(this.result)
            }
        }
        then(callBack) {
            if (this.state === 'success') {
                callBack(this.result)
            } else {
                this.successCallback = callBack
            }
            return this
        }
        catch(callBack) {
            if (this.state === 'fail') {
                callBack(this.result)
            } else {
                this.failCallback = callBack
            }
            return this
        }
    }

为了实现then函数的链式调用,需要执行then后将this实例返回,同时将successCallback参数变成数组,在调用的时候循环调用。而每一次then函数的返回值将作为下一次执行的时候的参数,所以得更新result参数,此时需要根据then函数的返回值判断一下是否是Promise本身,并且需要看state是否变为fail,如果状态在中间变为fail,则直接执行catch回调。并且后面的then函数不会再执行。同时定义两个静态函数resolve和reject,返回实例化对象,此对象只处理同步操作改变state状态。在successCallback中判断返回参数是否是Promise实例并判断状态。以下是完成代码

	class myPromise {
        state = 'pendding'
        result = null
        successCallback = []
        failCallback = null
        constructor(fun) {
            this.state = 'pendding'
            this.result = null
            fun(this.resolve, this.reject)
        }
        resolve = (data) => {
            if (this.state === 'pendding') {
                this.state = 'success'
                this.result = data
                if (this.successCallback && this.successCallback.length) {
                    this.successCallback.forEach(el => {
                        if (this.state === 'success') {
                            let res = el(this.result)
                            if (res instanceof myPromise) {
                                if (res.state === 'success') {
                                    this.result = res.result
                                    this.state = 'success'
                                } else if (res.state === 'fail') {
                                    this.state = 'pendding'
                                    this.reject(res.result)
                                }
                            } else if (res) {
                                this.result = res
                            }
                        }
                    })
                }
            }
        }
        reject = (data) => {
            if (this.state === 'pendding') {
                this.state = 'fail'
                this.result = data
                this.failCallback && this.failCallback(data)
            }
        }
        then(callBack) {
            if (this.state === 'success') {
                callBack(this.result)
            } else {
                this.successCallback.push(callBack)
            }
            return this
        }
        catch(callBack) {
            if (this.state === 'fail') {
                callBack(this.result)
            } else {
                this.failCallback = callBack
            }
            return this
        }
        static reject = (data) => {
            return new myPromise((a, b) => {b(data)})
        }
        static resolve = (data) => {
            return new myPromise((a, b) => {a(data)})
        }
    }
    let b = new myPromise((a, b) => {
        setTimeout(() => {
            a('aaaaa')
        }, 1000)
    })
    b.then((res) => {
        console.log('success:', res);
        return '新的'
    }).then(res => {
        console.log('success1:', res);
        return myPromise.reject('错的')
    }).then(res => {
        console.log('success2:', res);  // 这里不会执行,因为在上面的then中状态变为fail
    }).catch((res) => {
        console.log('error:', res);
    })
	// 执行结果:
	success: aaaaa
	success1: 新的
	error: 错的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值