理解Promise (4)

then 方法必须 返回一个新的promise

promise2 = promise1.then(onFulfilled, onRejected);

新的Promise 必须返回传递两个方法  onFulfilled, onRejected

If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).

onFulfilled, onRejected  其中的某个都要返回 一个value

if either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x)

如果onfulled或onrejected返回值x,请运行承诺解决过程[[解决]](promise2,x)。

 let x = onfulfilled(this.value);
                        // x是普通值还是promise 如果是普通值 直接调用promise2的resolve
                        // 如果是promise  那应该让x这个promise执行 x.then
  resolvePromise(promise2,x,resolve,reject);

这段代码是  resolvePromise    承诺解决过程

resolvePromise  这个函数里面 有Promise 这个参数,所以我们要拿到这个值 但是我们直接打印出来这个值 是 underfind 所以我们要用 promise2

这样,我们做到这里的时候  then 方法的大概结构就出来了 

 then(onfulfilled,onrejected){ 
        let promise2;
        promise2 = new Promise((resolve,reject)=>{
            if(this.status === 'fulfilled'){
                setTimeout(()=>{ 
                    try{
                        let x = onfulfilled(this.value);
                        // x是普通值还是promise 如果是普通值 直接调用promise2的resolve
                        // 如果是promise  那应该让x这个promise执行 x.then
                        resolvePromise(promise2,x,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                },0);
            }
            if(this.status === 'rejected'){
                setTimeout(()=>{
                    try{
                        let x = onrejected(this.reason);
                        resolvePromise(promise2,x,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                },0)
            }
            if(this.status === 'pending'){
                this.resolveCallbacks.push(()=>{
                    setTimeout(()=>{
                        try{
                            let x = onfulfilled(this.value);
                            resolvePromise(promise2,x,resolve,reject);
                        }catch(e){
                            reject(e);
                        }
                    },0)
                });
                this.rejectCallbacks.push(()=>{
                    setTimeout(()=>{
                        try{
                            let x = onrejected(this.reason);
                            resolvePromise(promise2,x,resolve,reject);
                        }catch(e){
                            reject(e);
                        }
                    },0)
                })
            }
        });
        return promise2
        
    }

接下来我们来处理   The Promise Resolution Procedure  的问题 

If promise and x refer to the same object, reject promise with a TypeError as the reason.

let  resolvePromise = (promise2,x,resolve,reject) => {
    if(promise2 === x){
        return reject(new TypeError('循环引用'))
    }
}

 if x is an object or function,

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

   }

Let then be x.then

  let then = x.then; // 如果取then方法出错 那就用错误拒绝promise2
  1. f/when resolvePromise is called with a value y, run [[Resolve]](promise, y).
  2. If/when rejectPromise is called with a reason r, reject promise with r.
  3. If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.

       

 if(typeof then === 'function'){ // 我就认为他是一个promise
                then.call(x,y=>{ // 让当前的promise执行 ,不用多次取then方法了
                    // y 有可能还是一个promise , 继续调用resolvePromise方法,直到解析出一个常量为止,最终把常量传递下去
                    if(called) return; // 放置此方法多次被调用
                    called = true;
                    resolvePromise(promise2,y,resolve,reject);
                },r=>{
                    if(called) return;
                    called = true;
                    reject(r); // 让当前的promise变成失败态即可
                })
            }else{
                // x就是一个普通的对象 并没有then方法
                resolve(x);
            }

全部的代码:

 

let  resolvePromise = (promise2,x,resolve,reject) => {
    // 判断x的类型 来处理promise2是成功还是失败
    // 所有的promise都遵循这个规范,不同的人写的promise可能会混用
    // 尽可能考虑的周全 要考虑别人promise可能出错的情况
    if(promise2 === x){
        return reject(new TypeError('循环引用'))
    }
    // 判断x是不是一个promise  ,这个x 可能不是自己的promise 所以为了安全 需要在进行校验,放置调一起用成功和失败 
    if(typeof x === 'function' || (typeof x === 'object' && x !== null)){
        // 尝试取当前x的then方法, 这个then方法可能别人定义的时候 用的Object.defineProperty 
        let called;
        try{
            let then = x.then; // 如果取then方法出错 那就用错误拒绝promise2
            if(typeof then === 'function'){ // 我就认为他是一个promise
                then.call(x,y=>{ // 让当前的promise执行 ,不用多次取then方法了
                    // y 有可能还是一个promise , 继续调用resolvePromise方法,直到解析出一个常量为止,最终把常量传递下去
                    if(called) return; // 放置此方法多次被调用
                    called = true;
                    resolvePromise(promise2,y,resolve,reject);
                },r=>{
                    if(called) return;
                    called = true;
                    reject(r); // 让当前的promise变成失败态即可
                })
            }else{
                // x就是一个普通的对象 并没有then方法
                resolve(x);
            }
        }catch(e){
            if(called) return;
            called = true;
            reject(e);
        }
    }else{
        // x肯定一个常量
        resolve(x);
    }
}

class Promise{
    constructor(executor){
        this.status = 'pending'; 
        this.value; 
        this.reason;
        this.resolveCallbacks = []; // 当then是pending 我希望吧成功的方法都放到数组中
        this.rejectCallbacks = [];
        let resolve = (value)=>{
            if(this.status == 'pending'){
                this.status = 'fulfilled';
                this.value = value;
                this.resolveCallbacks.forEach(fn=>fn()); // 发布
            }
        }
        let reject = (reason)=>{
            if(this.status === 'pending'){
                this.status = 'rejected';
                this.reason = reason;
                this.rejectCallbacks.forEach(fn=>fn())
            }
        }
        try{
            executor(resolve,reject);
        }catch(e){
            reject(e);
        }
    }
    then(onfulfilled,onrejected){ 
        let promise2;
        promise2 = new Promise((resolve,reject)=>{
            if(this.status === 'fulfilled'){
                setTimeout(()=>{ 
                    try{
                        let x = onfulfilled(this.value);
                        // x是普通值还是promise 如果是普通值 直接调用promise2的resolve
                        // 如果是promise  那应该让x这个promise执行 x.then
                        resolvePromise(promise2,x,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                },0);
            }
            if(this.status === 'rejected'){
                setTimeout(()=>{
                    try{
                        let x = onrejected(this.reason);
                        resolvePromise(promise2,x,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                },0)
            }
            if(this.status === 'pending'){
                this.resolveCallbacks.push(()=>{
                    setTimeout(()=>{
                        try{
                            let x = onfulfilled(this.value);
                            resolvePromise(promise2,x,resolve,reject);
                        }catch(e){
                            reject(e);
                        }
                    },0)
                });
                this.rejectCallbacks.push(()=>{
                    setTimeout(()=>{
                        try{
                            let x = onrejected(this.reason);
                            resolvePromise(promise2,x,resolve,reject);
                        }catch(e){
                            reject(e);
                        }
                    },0)
                })
            }
        });
        return promise2
        
    }
}
module.exports = Promise;

 

 

https://promisesaplus.com/

posted @ 2019-08-06 09:40  1点  阅读(180)  评论(0编辑  收藏  举报