手写promise

Promise的特点:

执行了resolve,Promise状态会变成fulfilled;

执行了reject,Promise状态会变成rejected;

Promise状态不可逆,第一次成功就永久为fulfilled,第一次失败就永远状态为rejected;

Promise中有throw的话,就相当于执行了reject;

 注意几个点我们依次去实现:

  1. Promise的初始状态是pending;

  2. 需要对resolve和reject绑定this:确保resolve和reject的this指向永远指向当前的MyPromise实例,防止随着函数执行环境的改变而改变

  3. Promise中有throw的话,就相当于执行了reject。这就要使用try catch了

  4. then方法,then接收两个回调,一个是成功回调,一个是失败回调;当Promise状态为fulfilled执行成功回调,为rejected执行失败回调;如resolve或reject在定时器里,则定时器结束后再执行then;then支持链式调用,下一次then执行受上一次then返回值的影响;

  5. 同时要注意执行顺序,promise回调属于微任务。

class MyPromise {
    constructor(excutor) {
        //初始化赋值
        this.initValue()
        try {
            excutor(this.resolve, this.reject)
        } catch (error) {
            this.reject(error)
        }
    }
    initValue() {
        this.promiseState = "pending"
        this.promiseResult = null
        //绑定到实例上
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
        //准备一个事件队列
        this.onFulfilledCallbacks = []
        this.onRejectCalbacks = []
    }
    resolve(value) {
        this.promiseState = "fulfilled"
        this.promiseResult = value
        while (this.onFulfilledCallbacks.length) {
            this.onFulfilledCallbacks.shift()(this.promiseResult)
        }
    }
    reject(reason) {
        this.promiseState = "rejected"
        this.promiseResult = reason
        while (this.onRejectCalbacks.length) {
            this.onRejectCalbacks.shift()(this.promiseResult)
        }
    }
    then(onFulfilled, onReject) {
        //判断为函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
        onReject = typeof onReject === 'function' ? onReject : reason => { throw reason }


        //保证then的返回是个promise对象,实现链式调用
        const thenPromise = new MyPromise((resolve, reject) => {
            const handlePromise = cb => {
                //模拟异步任务
                setTimeout(() => {
                    try {
                        const result = cb(this.promiseResult)
                        if (result === thenPromise) {
                            throw new Error('not self')
                        }
                        //如果是promise就调用链式.then,否则就抛出结果
                        if (result instanceof MyPromise) {
                            result.then(resolve, reject)
                        } else {
                            resolve(result)
                        }
                    } catch (error) {
                        reject(error)
                        throw new Error(error)
                    }
                })
            }
            if (this.promiseState == 'fulfilled') {
                // onFulfilled(this.promiseResult
                handlePromise(onFulfilled)
            } else if (this.promiseState == 'rejected') {
                // onReject(this.promiseResult)
                handlePromise(onReject)
            } else {
                //针对异步 使用队列存储 等执行到resolve或reject后再执行
                // this.onFulfilledCallbacks.push(onFulfilled)
                // this.onRejectCalbacks.push(onReject)
                this.onFulfilledCallbacks.push(handlePromise(onFulfilled))
                this.onRejectCalbacks.push(handlePromise(onFulfilled))

            }
        })
        return thenPromise
    }
}

new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve(123)
    }, 2000)
}).then(res => {
    console.log(res);
})
console.log(1);
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Goat恶霸詹姆斯

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

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

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

打赏作者

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

抵扣说明:

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

余额充值