Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

promise类实现 #19

Open
nianxiongdi opened this issue Apr 7, 2020 · 0 comments
Open

promise类实现 #19

nianxiongdi opened this issue Apr 7, 2020 · 0 comments

Comments

@nianxiongdi
Copy link
Owner

nianxiongdi commented Apr 7, 2020

class Promise {
    constructor(executor){
        // executor();

        this.state = 'pending'; // 状态
        this.value = undefined; // 成功的值
        this.reason = undefined; //失败的原因

        // 成功的时候
        this.onResolveCallback = []; // then多次的时候, 所以要使用数组保存
        // 失败的时候
        this.onRejectedCallback = [];

        const resolve = value=>{
            if(this.state === 'pending'){
                this.state = 'fulfiled';
                this.value = value;
                // console.log(this.value);
                // 发布消息
                this.onResolveCallback.forEach(fn=> fn());// 当有定时器的时候,setTimeout( ()=> resolve(1) , 100))
            }
        }

        const reject = reason=>{
            if(this.state === 'pending'){
                this.state = 'rejected';
                this.reason = reason;

                this.onRejectedCallback.forEach(fn=>fn());
            }
        }

        try{
            executor(resolve, reject);
        }catch(err) {
            console.log(err);
        }
    }

    then(onFuilfilled, onRejected) {

        const promise2 = new Promise((resolve, reject)=>{
            if(this.state === 'fulfiled'){
                const x = onFuilfilled(this.value); // 可能是一个promise 或普通的值
                
                setTimeout(()=>{
                    resolvePromise(promise2, x, resolve, reject);// 因为这个promise2的值还得不到, 需要使用红任务出从处理,进入下一个时间循环
                }, 0);
                
            }
            
            if(this.state === 'rejected') {
                setTimeout(()=> {
                    const x = onRejected(this.reason);
                    resolvePromise(promise2, x, resolve, reject);// 因为这个promise2的值还得不到, 需要使用红任务出从处理,进入下一个时间循环
                },0)
            }
    
            if(this.state === 'pending'){ // 当Promise中有定时器的时候(setTimeout( ()=> resolve(1) , 100)), then方法是顺序执行的,resolve还没有执行,需要放入到对应的callback队列中
                // 订阅
                // 多个then的时候
                this.onResolveCallback.push(()=>{
                    setTimeout(()=> {
                        const x= onFuilfilled(this.value);
                        resolvePromise(promise2, x, resolve, reject);
                    }, 0);
                })
                this.onRejectedCallback.push(()=>{
                    setTimeout(() => {
                        const x = onRejected(this.reason);
                        resolvePromise(promise2, x, resolve, reject);
                    }, 0);
                })
            }
        })

        return promise2;
    }


    // catch
    catch(onRejected) {
        return this.then(null, onRejected);
    }

    // finally
    /*
        Promise.prototype.finally = function (callback) {
            let P = this.constructor;
            return this.then(
                value  => P.resolve(callback()).then(() => value),
                reason => P.resolve(callback()).then(() => { throw reason })
            );
        };

    */

    finally(callback) {
        return this.then(
            (res) => {
                callback();
                return res;
            },
            (err) => {
                callback();
                return err;
            }
        );
    }

   // return constructor.resolve(callback()).then(() => throw reason)


//    Promise.prototype.finally = function (callback) {
//     let P = this.constructor;
//     return this.then(
//         value  => P.resolve(callback()).then(() => value),
//         reason => P.resolve(callback()).then(() => { throw reason })
//     );
// };

    // all
    static all(promises){
        let arr = [];
        let index = 0;
        let len = promises.length;

        return new Promise((resolve, reject) => {
            for(let i=0; i<len; i++) {
                promises[i].then(res=>{
                    arr.push(res);
                    index++;
                    if(index === len){
                        resolve(arr);
                    }
                }, err => {
                    reject(err);
                })
            }
        })
    }
    // const p = Promise.race([p1, p2, p3]);
    // 上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
    static race(promises) {
        return new Promise((resolve, reject)=> {
            Array.isArray(promises) && promises.forEach(promise => {
                promise.then(resolve, reject);
            })
        })
    }

    // Promise.resolve('reason');
    // 内部返回一个promise
    static resolve(res) {
        return new Promise((resolve, reject) => {
            resolve(res);
        })
    }

    // Promise.reject('error')
    // 内部返回一个promise对象
    static reject(err){
        return new Promise((resolve, reject)=> {
            reject(err);
        })
    }
}


const resolvePromise = (promise2, x, resolve, reject) => {
    // console.log(promise2, x, resolve, reject);
    
    if(promise2 === x){
        return reject(new TypeError('循环引用!!!'));
    }

 
    if(typeof x === 'function' || (typeof x === 'object' && x !== null)){ 
        try{

            const then = x.then;
            /*
                promise.then(res=>console.log(res))
                promise.then(res=> new Promise(resolve=> resolve(1)))
                Promise.resolve('ok').then(res=> new Promise(resolve=> resolve(1)))
            */
            if(typeof then === 'function') { // 认为是promise
                then.call(x,y=>{ // 这段代码666,  这里是执行方法 x.then(y=>{}, r=>{})
                    // resolve(y); //修改为递归解析
                    // console.log(y)
                    resolvePromise(promise2, y, resolve, reject);
                }, r=>{ // 相当于是reject方法
                    reject(r)
                });
            }

        }catch(err) {
            console.log(err);
        }
    }else { // 不是promise 直接进行返回
        resolve(x);
    }
    
}


module.exports = Promise;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant