自己实现的promise

跟着大牛老师学的,手写一个promise,话不多说,直接放代码。

var MyPromise = (() => {
    const PENDING = 'pending',
        FULLFILLED = 'fullfilled',
        REJECT = 'reject',
        PromiseState = Symbol('PromiseState'),
        PromiseResult = Symbol('PromiseResult'),
        changeState = Symbol('changeState'),
        thenableList = Symbol('thenableList'),
        catchableList = Symbol('catchableList'),
        addPromiseMethod = Symbol('addPromiseMethod'),
        exePromiseMethod = Symbol('exePromiseMethod'),
        linkPromise = Symbol('linkPromise'),
        isFunction = (func) => {
            return typeof func === 'function'
        };

    const MyPromise = class {
        // 改变状态
        [changeState](state, value) {
            this[PromiseResult] = value;
            // 改变promise状态
            if (this[PromiseState] === PENDING) {
                // 已经改变状态的就不能再改变了
                this[PromiseState] = state
                setTimeout(() => {
                    if (this[PromiseState] === FULLFILLED) {
                        this[exePromiseMethod](this[thenableList])
                    } else {
                        this[exePromiseMethod](this[catchableList])
                    }
                }, 0)
            }

        }
        // 添加执行函数
        [addPromiseMethod](queue, method, state) {
            if (isFunction(method)) {
                queue.push(method);
                // 如果该状态已经是fullfill则直接执行
                if (this[PromiseState] === state) {
                    this[exePromiseMethod](queue)
                }
            }
        }
        // 执行
        [exePromiseMethod](queue) {
            queue.forEach(func => func(this[PromiseResult]))
        }
        // 返回的promise混入用户的执行方法
        [linkPromise](queue, method, state) {
            // 把用户的thenable函数和catchable函数混入promise,在then和catch方法返回新的MyPromise,用于链式调用
            return new MyPromise((resolve, reject) => {
                this[addPromiseMethod](queue, (param) => {
                    try {
                        // 获取thenable函数和catchable函数的执行结果
                        let result = method(param);
                        // 如果是MyPromise类型 则执行后改变新MyPromise
                        if (result instanceof MyPromise) {
                            // 新MyPromise的状态和用户返回的MyPromise状态保持一致
                            result.then(res => {
                                resolve(res)
                            }, err => {
                                reject(err)
                            })
                        } else {
                            resolve(result);
                        }

                    } catch (e) {
                        reject(e)
                    }
                }, state)
            })
        }
        // executor 生成promise实例时传递的unsettle状态的执行方法
        constructor(executor) {
            // 如果不是函数也不是MyPromise类型,抛出异常
            if (!isFunction(executor)) {
                throw new TypeError('Promise resolver undefined is not a function')
            }
            // 默认为pending状态
            this[PromiseState] = PENDING;
            // 默认为pending状态
            this[PromiseResult] = undefined;
            // 默认结果值未undefined
            this[thenableList] = [];
            this[catchableList] = [];
            // 改变状态的入口方法
            const changeStateEntry = (state,value)=>{
                // 如果是MyPromise则执行后改变状态
                if (value instanceof MyPromise) {
                    value.then(res => {
                        resolve(res)
                    }, err => {
                        reject(err)
                    })
                } else {
                    // 如果不是则改变状态
                    setTimeout(() => {
                        this[changeState](state, value)
                    }, 0)
                }
            }
            // 如果直接调用则在executor立马调用resolve 或reject时初始化的MyPomise状态不是pending
            const resolve = (value) => {
                changeStateEntry(FULLFILLED,value)
            }
            // 如果直接调用则在executor立马调用resolve 或reject时初始化的MyPomise状态不是pending
            const reject = (value) => {
                changeStateEntry(REJECT,value)
            }
            // 在最后执行,并两个形参,一个是resolve函数,一个是reject函数
            // 如果executor执行失败则自动调用reject
            try {
                executor(resolve, reject)
            } catch (e) {
                // 执行异常时promise的状态立即为reject
                this[changeState](REJECT, e)
                setTimeout(() => {
                    throw e;
                }, 0)
            }

        }
        // then方法
        // 有两个参数,一个是thenable方法,一个是catchable方法,
        then(thenable, catchable) {
            let pro = this[linkPromise](this[thenableList], thenable, FULLFILLED)
            this.catch(catchable)
            return pro

        }
        // catch方法
        // 一个参数
        catch (catchable) {
            return this[linkPromise](this[catchableList], catchable, REJECT)
        }
    }
    return MyPromise
})()

var pro = new MyPromise((resolve, reject) => {
    resolve(new MyPromise((a, b) => {
        setTimeout(() => {
            console.log('执行了')
            a(22)
        }, 1000)
    }))
}).then((res) => {
    return new MyPromise((a, b) => {
        setTimeout(() => {
            a(24)
        }, 1000)
    })
}, (err) => {
    console.log('err', err)
}).then((res) => {
    console.log(res)
}, err => {
    console.log('err', err)
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值