手写源代码(三)——promise原理

手写promise原理

话不多说,直接上代码。

//第一步:控制状态的变化 
// 1.未决阶段执行的函数  
// 2.状态更改一次后不能再更改  
// 3.抛出错误用try catch
//第二步:实现后续的处理 
//thenable--resolved catchable--rejected
// then方法 加到队列里面去 已经是resolved则立即执行,否则加到队列里去
//第三步:串联promise,
//在新的promise对象里面让thenable catchable执行并记录返回的数据

const MyPromise = (() => {
    const pending = "pending",
        resolved = "resolved",
        rejected = "rejected",
        PromiseValue = Symbol("PromiseValue"),//状态数据
        PromiseStatus = Symbol("PromiseStatus"),//当前状态
        changeStatus = Symbol("changeStatus"),//改变状态的函数
        thenables = Symbol("thenables"),//成功的队列
        catchables = Symbol("catchables"),//失败的队列
        settleHandler = Symbol("settleHandler"),//后续处理的函数
        linkPromise = Symbol("linkPromise");//返回新的promise

    return class MyPromise {
        /**
         * 
         * @param {*} newStatus 
         * @param {*} newValue 
         */
        [changeStatus](newStatus, newValue, queue) {
            if (this[PromiseStatus] !== pending) {
                //状态无法变更
                return;
            }
            this[PromiseStatus] = newStatus;
            this[PromiseValue] = newValue;
            //执行相应队列中的函数
            queue.forEach(handler => {
                handler(newValue);
            });
        }
        /**
         * 后续处理的函数
         * @param {*} handler 
         * @param {*} status 
         * @param {*} queue 
         */
        [settleHandler](handler, status, queue) {
            if (this[PromiseStatus] === status) {
                setTimeout(() => {
                    handler(this[PromiseValue]);
                }, 0)

            } else {
                queue.push(handler);
            }
        }
        [linkPromise](thenable, catchable) {
            return new MyPromise((resolve, reject) => {
                this[settleHandler](data => {
                    try {
                        const result = thenable(data);//得到当前promise的处理结果
                        if (result instanceof MyPromise) {
                            result.then(d => {
                                resolve(d);
                            }, err => {
                                reject(err);
                            })
                        } else {
                            resolve(result);
                        }

                    } catch (err) {
                        reject(err)
                    }
                }, resolved, this[thenables])

                this[settleHandler](reason => {
                    try {
                        const result = catchable(reason);//得到当前promise的处理结果
                        if (result instanceof MyPromise) {
                            result.then(d => {
                                resolve(d);
                            }, err => {
                                reject(err);
                            })
                        } else {
                            resolve(result);
                        }

                    } catch (err) {
                        reject(err)
                    }
                }, rejected, this[catchables])
            })
        }
        /**
        * 
        * @param {*} executor 未决阶段下的处理函数
        */
        constructor(executor) {
            this[PromiseStatus] = pending;
            this[PromiseValue] = undefined;
            this[thenables] = [];
            this[catchables] = [];

            const resolve = data => {//写箭头函数 ,避免this指向出错
                this[changeStatus](resolved, data, this[thenables]);//在状态改变的时候加入到对应的队列
            }
            const reject = reason => {
                this[changeStatus](rejected, reason, this[catchables]);
            }
            try {
                executor(resolve, reject);
            } catch (err) {
                reject(err);
            }

        }
        then(thenable, catchable) {
            // this[settleHandler](thenable,resolved,this[thenables]);
            // this.catch(catchable);
            return this[linkPromise](thenable, catchable);
        }
        catch(catchable) {
            // this[settleHandler](catchable,rejected,this[catchables]);
            return this[linkPromise](undefined, catchable);
        }
        static all(proms) {//所有的promise全部完成之后就完成,一个有错误就错误
            return new MyPromise((resolve,reject)=>{
                const results = proms.map(p=>{
                    const obj = {
                        result:undefined,
                        isResolved:false
                    }
                    p.then(data=>{
                        obj.result = data;
                        obj.isResolved = true;
                        //判断是否全部完成
                        const unResolved = results.filter(r=>!r.isResolved);
                        if(unResolved.length === 0){
                            //全部完成
                            resolve(result.map(r=>r.result));
                        }
                    },reason=>{
                        reject(reason);
                    })
                    return obj;
                })
            })
        }

        static race(proms){
            return new MyPromise((resolve,reject)=>{
                proms.forEach(p=>{
                    p.then(data=>{//有一个完成就完成
                        resolve(data);
                    },err=>{//有一个失败就失败
                        reject(err);
                    })
                })
            })
        }

        static resolve(data) {
            if (data instanceof MyPromise) {
                return data;
            } else {
                return new MyPromise(resolve => {
                    resolve(data);
                })
            }
        }

        static reject(reason) {
            return new MyPromise((resolve,reject) => {
                reject(reason);
            })
        }
    }
 
})()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值