Promise源码分析

实现原理:说到底,Promise 也还是使用回调函数,只不过是把回调封装在了内部,使用上一直通过 then 方法的链式调用,使得多层的回调嵌套看起来变成了同一层的,书写上以及理解上会更直观和简洁一些。

我这里只是实现了部分的功能,并非和源码一模一样!希望里面不足的地方,小伙伴们多多指正

//我们首先来定义一个MyPromise类,我在这里使用立即执行函数的方式,防止变量全局污染。
const MyPromise = (() => {
    // 定义三种状态
    const PENDING = "pending";
    const RESOLVED = "resolved";
    const REJECTED = "rejected";

    //这里使用Symbol定义不让外界访问的符号属性,状态和数据
    const PromiseResult = Symbol("PromiseResult")
    const PromiseState = Symbol("PromiseState")

    const changeStatus = Symbol("changeStatus")

    // 定义两个任务队列:成功的后续处理和失败后续处理
    const thenables = Symbol("thenables")
    const catchables = Symbol("catchables")

    const settleHandle = Symbol("settleHandle")

    return class MyPromise {
        /*
            newStatus 新的状态
            newValue 新的值
            queue 执行的任务队列
        */
        [changeStatus](newStatus, newValue, queue) {
            if (this[PromiseState] !== PENDING) {
                return
            }
            this[PromiseState] = newStatus;
            this[PromiseResult] = newValue;
            // console.log(queue)
            queue.forEach(element => {
                // console.log(element)
                return element(newValue)
            });
        }
        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[changeStatus](RESOLVED, data, this[thenables])
            }
            const reject = reason => {
                // if(this[PromiseState] !== PENDING){
                //     return
                // }
                // this[PromiseState] = REJECTED;
                // this[PromiseResult] = reason;
                this[changeStatus](REJECTED, reason, this[catchables])
            }
            // executor(resolve,reject)
            try {
                executor(resolve, reject)
            } catch (error) {
                reject(error)
            }
        }
        then(thenable, catchable) {
            // if(this[PromiseState] === RESOLVED){
            //     thenable(this[PromiseResult])
            // }else{
            //     this[thenables].push(thenable)
            // }
            this[settleHandle](thenable, RESOLVED, this[thenables])
            this.catch(catchable)
        }
        catch (catchable) {
            // if(this[PromiseState] === REJECTED){
            //     catchable(this[PromiseResult])
            // }else{
            //     this[catchables].push(catchable)
            // }
            this[settleHandle](catchable, REJECTED, this[catchables])
        }
        // 提取公共代码
        /*
            handler 后续处理函数
            immediateStatus 立即执行的状态
            queue 任务队列
        */
        [settleHandle](handler, immediateStatus, queue) {
            if (this[PromiseState] === immediateStatus) {
                setTimeout(() => {
                    handler(this[PromiseResult])
                }, 0)
            } else {
                queue.push(handler)
            }
        }
        static resolve(data) {
            if (data instanceof MyPromise) {
                return data
            } else {
                return new MyPromise(res => {
                    res(data)
                })
            }
        }
        static reject(resaon) {
            return new MyPromise((res, rej) => {
                rej(resaon)
            })
        }
        static all(proms) {
            return new MyPromise((resolve, reject) => {
                const results = proms.map(p => {
                    const obj = {
                        res: undefined,
                        isResolved: false
                    }
                    p.then(data => {
                        obj.res = data;
                        obj.isResolved = true;
                        const unResolved = results.filter(r => !r.isResolved)
                        if (unResolved.length === 0) {
                            // 全部都是resolve
                            resolve(results.map(r => r.res))
                        }
                    }, reson => {
                        reject(reson)
                    })
                    return obj;
                })
            })
        }
        static race(proms) {
            return new MyPromise((resolve, reject) => {
                proms.forEach(p =>{
                    p.then(data=>{
                        console.log(11)
                        resolve(data)
                    },err=>{
                        console.log(22)
                        reject(err)
                    })
                })
            })
        }
    }
})()

这个记录下来为了以后的使用的方便,也希望大佬们多多交流,多多留言,指出我的不足的之处啦!

有需要的小伙伴自取啦!!

猜你喜欢

转载自blog.csdn.net/A20201130/article/details/123782960