天天看点

个人对于promise的封装与实现

//分析以下Promise实例

// new Promise((res,rej)=>{

// // console.log(‘111’);

// // console.log(res);

// // console.log(rej);

// // res(‘chenggong’);

// throw new Error(‘21’);

// });

/*

1.实例化promise时需要传参数(res,rej),

所以在写源码时候必须构建

2.res和rej都是函数可以执行,调用

3.参数resolve  和 reject  是不是原型上的
或者是否是实例上的 
    验证:如果上原型或者实例上,我们直接打印
            let p = new Promise((resolve,reject)=>{

            });

            console.log(p.resolve);
            此时他会出现值,但是结果是undefind
            所以它既不是原型上的,也不是实力上的 

4.then(onfulfiled,onrejected)
    onfulfiled成功时候调用
    onrejected失败时候掉用
成功或者失败的状态需要判断此时的状态
           

*/

以上肥西并不完全

//promise的三种状态
//等待态
const PENDING = "PENDING";
//成功态
const RESOLVE = "RESOLVE";
//失败态
const REJECT = "REJECT";

function resolvePromise(promise4, x, resolve, reject) {
    if (x === promise4) {
        return reject(new TypeError('[TypeError: Chaining cycle detected for promise #<Promise>]123'));
    }
    let called;
    if (typeof x === 'object' && x != null || typeof x === 'function') {
        try {
            let then = x.then;
            if (typeof then === 'function') {
                then.call(x, y => {
                    //y是x执行正确的时候调用
                    if (called) return;
                    called = true;
                    resolvePromise(promise4, y, resolve, reject);
                }, r => {
                    //
                    if (called) return;
                    called = true;
                    reject(r);
                });
            } else {
                resolve(x);
            }
        } catch (error) {
            if (called) return;
            called = true;
            reject(error);
        }

    } else {
        //普通值
        resolve(x);
    }
}
class Promise {
    //创建构造函数
    //executor是一个执行器,会马上执行
    constructor(executor) {
        //等待状态
        this.status = PENDING;
        //记录成功原因
        this.value = undefined;
        //记录失败原因
        this.reason = undefined;
        //当在执行异步任务时
        this.resolveCallbacks = [];
        this.rejectCallbacks = [];
        let resolve = (value) => {
            //辱国一开始的状态就是等待态,在执行状态改变
            if (this.status === PENDING) {
                this.status = RESOLVE;
                this.value = value;
                this.resolveCallbacks.forEach(fun => fun());
            }
        };

        let reject = (reason) => {
            if (this.status === PENDING) {
                this.status = REJECT;
                this.reason = reason;
                this.rejectCallbacks.forEach(fun => fun());
            }
        };

        //一旦失败就直接调用reject
        try {
            executor(resolve, reject);
        } catch (error) {
            reject(error);
        }

    }

    //实现then方法  then是原型的
    then(onfulfiled, onrejected) {
        onfulfiled = typeof onfulfiled === 'function' ? onfulfiled : val => val;
        onrejected = typeof onrejected === 'function' ? onrejected : err => { throw err }


        let promise4 = new Promise((resolve, reject) => {
            if (this.status === RESOLVE) {
                setTimeout(() => {
                    try {
                        let x = onfulfiled(this.value);
                        resolvePromise(promise4, x, resolve, reject);
                    } catch (error) {
                        reject(error);
                    }
                });
            }

            if (this.status === REJECT) {
                setTimeout(() => {
                    try {
                        let x = onrejected(this.reason);
                        resolvePromise(promise4, x, resolve, reject);
                    } catch (error) {
                        reject(error);
                    }
                });
            }

            //当状态是等待态时候我们将所有的数据存储起来
            if (this.status === PENDING) {
                // this.resolveCallbacks.push(onfulfiled);
                // this.rejectCallbacks.push(onrejected);
                this.resolveCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            let x = onfulfiled(this.value);
                            resolvePromise(promise4, x, resolve, reject);
                        } catch (error) {
                            reject(error);
                        }
                    });
                })


                this.rejectCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            let x = onrejected(this.reason);
                            resolvePromise(promise4, x, resolve, reject);
                        } catch (error) {
                            reject(error);
                        }
                    });

                })
            }
        });
        return promise4;
    }
};

//测试代码入口
Promise.defer = Promise.deferred = function() {
    let dfd = {};
    dfd.promise = new Promise((resolve, reject) => {
        dfd.resolve = resolve;
        dfd.reject = reject;
    });

    return dfd;

}

module.exports = Promise;
           

测试结果完全通过

继续阅读