【es6系列】手写Promise

前言:Promise作为解决异步问题的一种方案,成功替代了以往的callback回调函数,在如今的开发中广泛使用,所以它的实现原理更需要掌握。

Promise分为三种状态,分别是:

  • pedding:进行中
  • fulfilled:成功

  • rejected:失败

Promise状态一旦确定,变为fulfilled或rejected后,将不可更改;抱着这样的思路,我们将实现一个基础功能的Promise。

实现思路:

1、首先Promise是一个类,它接收一个执行器executor(函数),并且这个函数会立即执行;

2、执行器executor接收两个回调函数作为参数,分别代表resolve与reject;

3、解决异步问题:存储then中的回调函数,当resolve或reject触发后,再依次执行;

4、then中的返回值会作为下个then回调函数的参数;

按照上面思路,代码实现如下:


class YPromise{
    // Promise的三种状态,pedding-> fulfilled,pedding-> rejected,不可逆
    static PEDDING = 'pedding'
    static FULFILLED = 'fulfilled'
    static REJECTED = 'rejected'
    // 成功状态保存值
    #value = null
    // 失败状态保存值
    #reason = null
    constructor(callback){
        try {
            this.status = 'pedding'
            // 保存成功回调
            this.fulfilledCallbacks = []
            // 保存失败回调
            this.rejectedCallbacks = []
            callback(YPromise.resolve.bind(this),YPromise.reject.bind(this))
        } catch (error) {
            YPromise.catch(error)
        }
    }
    static resolve(res){
        if(this.status === YPromise.PEDDING || this.status === YPromise.FULFILLED){
            this.status = YPromise.FULFILLED
            this.value = res
            queueMicrotask(() => {
                this.fulfilledCallbacks.forEach(fn => {
                    let res = fn(this.value)
                    res && (this.value = res)
                })
            })
        }
    }
    static reject(err){
        if(this.status === YPromise.PEDDING){
            this.status = YPromise.REJECTED
            this.reason = err
            queueMicrotask(() => {
                this.rejectedCallbacks.forEach(fn => fn(this.reason))
            })
        }
    }
    then(resolveFn,rejectFn){
        resolveFn = typeof resolveFn === 'function' ? resolveFn : () => {}
        rejectFn = typeof rejectFn === 'function' ? rejectFn : () => {}
        if(this.status === YPromise.PEDDING || this.status === YPromise.FULFILLED){
            this.fulfilledCallbacks.push(resolveFn)
        }else {
            this.rejectedCallbacks.push(rejectFn)
        }
        return this
    }
    catch(rejectFn){
        rejectFn = typeof rejectFn === 'function' ? rejectFn : () => {}
        if(this.status === YPromise.PEDDING || this.status === YPromise.REJECTED){
            this.rejectedCallbacks.push(rejectFn)
        }
        return this
    }
}
 
new YPromise((resolve,reject) => {
    setTimeout(() => {
        resolve('then成功')
    },2000)
})
.then(res => {
    console.log('then1',res);
    return 1111
})
.catch(err => {
    console.log('err');
}).then(res => {
    console.log(res);
})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值