模拟Promise() 源码

1.模拟all()方法

        在Promise函数中的  all() 方法里面,能够实现在多个Promise对象里面,如果状态全部为resolve的话,则all() 方法返回的结果是resolve,并将所有的Promise对象放到一个数组里面;如果有一个状态为reject的话,则all()方法返回的结果是reject,将第一个出现reject对象的下标作为PromiseResult的值。演示代码如下

<script>
     static all(proms) {
            return new MyPromise((resolve, reject) => {
                const res = proms.map(p => {
                    const obj = {
                        result: undefined,
                        isResolved: false
                    }
                    p.then(data => {
                        obj.result = data;
                        obj.isResolved = true;
                        const unResolved = res.filter(r => !r.isResolved)
                        if (unResolved.length === 0) {
                            // 全是resolved
                            resolve(res.map(r => r.result))
                        }
                    }, err => {
                        reject(err)
                    })
                    return obj
                })
            })
        }
</script>

 2.模拟race() 方法

在Promise函数中的  race() 方法里面,能够实现在多个Promise对象里面,谁的对象状态先推出来,那么PromiseState就显示谁的状态,PromiseResult为最先推出的那个index值,如果是resolve就是resolve,反之则为reject。演示代码如下。

<script>
     static race(proms) {
            return new MyPromise((resolve, reject) => {
                proms.forEach(p => {
                    p.then(data => {
                        resolve(data)
                    }, err => {
                        reject(err)
                    })
                })
            })
        }
</script>

总体代码如下:

const MyPromise = (() => {
    // 定义三种状态
    const PENDING = 'pending';
    const RESOLVED = 'resolved';
    const REJECTED = 'rejected';

    // 不让外界访问,定义符号属性,状态,数据
    const PromiseResult = Symbol('PromiseResult');
    const PromiseState = Symbol('PromiseState');

    // 定义两个任务队列,存储成功后的后续处理和失败后的后续
    const thenables = Symbol('thenables');
    const catchables = Symbol('catchables');


    const changeState = Symbol('changeState');

    const settleHandle = Symbol('settleHandle');

    const linkPromise = Symbol('linkPromise');

    return class Mypromise {
        constructor(executor) {
            this[PromiseState] = PENDING;
            this[PromiseResult] = undefined;

            // 定义任务队列数组
            this[thenables] = [];
            this[catchables] = [];

            // 定义成功或失败的推向函数
            const resolve = data => {
                // 只能单向推状态
                // if(this[PromiseState] !== PENDING){
                //     return ;
                // }
                // // 只能是未决到已决
                // this[PromiseState] = RESOLVED;
                // this[PromiseResult] = data

                this[changeState](RESOLVED, data, this[thenables])
            }
            const reject = reason => {
                // 只能单向推状态
                // if(this[PromiseState] !== PENDING){
                //     return ;
                // }
                // // 未决到已决
                // this[PromiseState] = RESOLVED;
                // this[PromiseResult] = data;

                this[changeState](REJECTED, data, this[thenables])
            }
            // executor(resolve,reject)
            // 从未决阶段推向已决阶段不仅可以使用resolve和reject函数,也可以使用抛出错误的方式
            try {
                executor(resolve, reject)
            } catch (error) {
                reject(error)
            }
        }



        // 定义改变状态的方法
        // newState 新的状态
        // newValue 新的数据
        // queue 任务队列
        [changeState](newState, newValue, queue) {
            if (this[PromiseState] !== PENDING) {
                return;
            }
            // 只能是未决到已决
            this[PromiseState] = newState;
            this[PromiseResult] = newValue;

            queue.forEach(handle => handle(newValue));
        }


        // 定义then方法
        then(thenable, catchable) {
            // 1.需要将thenable和catchable放入任务队列中等待promise为已决阶段时执行
            // if(this[PromiseState] === RESOLVED){
            //     // 如果是resolved状态则可以执行thenable
            //     thenable(this[PromiseResult])
            // }else{
            //     this[thenables].push(thenable)  // 只是放入并没有执行
            // }
            // // 直接调用catch处理失败

            // this[settleHandle](RESOLVED,thenable,this[thenables])
            // this.catch(catchable)


            return this[linkPromise](thenable, catchable)
        }

        catch (catchable) {
            // if(this[PromiseState] === REJECTED){
            //     // 如果是resolved状态则可以直击接执行thenable
            //     catchable(this[PromiseResult])
            // }else{
            //     this[catchables].push(catchable)  // 只是放入还没有执行
            // }
            // this[settleHandle](REJECTED,catchable.this[catchables])

            return this[linkPromise](undefined, catchable)
        }

        // 提取then和catch的公共代码
        // immediateState 立即执行的状态
        // handler 后续处理函数
        // queue  任务队列
        [settleHandle](immediateState, handle, queue) {
            if (typeof handle !== 'function') {
                return;
            }
            if (this[PromiseState] === immediateState) {
                // 如果是resolved 状态则可以直接执行thenable
                // 异步微任务  只能使用宏任务模拟
                setTimeout(() => {
                    handle(this[PromiseResult])
                }, 0);
            } else {
                queue.push(handle) //只是放入还没有执行
            }
        }

        // 定义串联函数
        // thenable : fun
        [linkPromise](thenable, catchable) {
            function exec(data, handle, resolve, reject) {
                try {
                    // 得到一个Promise的处理结果
                    const result = handle(data)
                    if (result instanceof MyPromise) {
                        result.then(d => {
                            resolve(d)
                        }, err => {
                            reject(err)
                        })
                    } else {
                        resolve(result)
                    }
                } catch (error) {
                    reject(error)
                }
            }

            // 1.该函数执行完后需要返回一个promise对象
            // 2.完成基础功能:settleHandle
            return new MyPromise((resolve,reject) =>{
                this[settleHandle](RESOLVED,data =>{  //qwe
                    exec(data,thenable,resolve,reject)
                },this[thenables])
                this[settleHandle](REJECTED,reason =>{
                    exec(reason,catchable,resolve,reject)
                },this[catchables])
            })
        }

        static all(proms) {
            return new MyPromise((resolve, reject) => {
                const res = proms.map(p => {
                    const obj = {
                        result: undefined,
                        isResolved: false
                    }
                    p.then(data => {
                        obj.result = data;
                        obj.isResolved = true;
                        const unResolved = res.filter(r => !r.isResolved)
                        if (unResolved.length === 0) {
                            // 全是resolved
                            resolve(res.map(r => r.result))
                        }
                    }, err => {
                        reject(err)
                    })
                    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(data) {
            return new MyPromise((resolve, reject) => {
                reject(data)
            })
        }
    }
})()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值