Promise源码解密-then的链式调用

},error=>{

    return error

}).then(

  (res) => {

    console.log(res.toString(),'res===='); // ReferenceError: a is not defined res====

  },

  (error) => {

    console.log(error);

  }

);



```
  1. then中的onFulfilled/onReject 是可选的, 下面的例子,第一个then没有return值,但是第二个then也可以接受到值,最终输出 then 回调可选。

    
    let t = new Promise((resolve, reject) => {
    
        resolve('then 回调可选')
    
    })
    
    t.then().then(
    
      (res) => {
    
        console.log(res);
    
      },
    
      (error) => {
    
        console.log(error);
    
      }
    
    );
    
    
    
    
  2. 实例不可 循环引用,报错 : Chaining cycle detected for promise #


let p = new Promise((resolve, reject) => {

    resolve('不可循环引用')

})

var p2=p.then(()=>{

   return p2 // 返回的值还是p2

})



完整代码


// 定义状态常量

const STATUS_PENDING = "pending";

const STATUS_FULFILLED = "fulfilled";

const STATUS_REJECTED = "rejected";



function resolvePromise(promise2, x, resolve, reject) {

    // 用来保存是否已经reject或者resolve过

    let called

    if (promise2 === x) {

        throw new TypeError('Chaining cycle detected for promise')

    }

    // 如果是函数或者object的话先默认是promise

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

        try {

            let then = x.then

            // 如果then是函数的话

            if (typeof then === 'function') {

                // 为啥不直接x.then()

                // 因为then已经判断过是不是function,但是x.then没有判断过

                // 就让then执行 第一个参数是this   后面是成功的回调 和 失败的回调



                //  这里的y是啥,如果x是promsie的话,那么y就是x中的resolve/reject的值

                then.call(x, y => {

                    // 成功和失败只能调用一个



                    if (called) return;

                    called = true;

                    console.log(y, 'yyyyyyyyyyyy')



                    // resolve的结果依旧是promise 那就继续解析

                    resolvePromise(promise2, y, resolve, reject);

                }, err => {

                    // 成功和失败只能调用一个



                    if (called) return;

                    called = true;

                    reject(err);

                })

            } else {



                resolve(x); // 如果不是函数,那就直接返回结果

            }

        } catch (error) {

            // 成功和失败只能调用一个



            if (called) return;

            called = true;

            // 没有then 不是函数也不是普通值

            reject(error)

        }

    } else {

        // x 是一个普通值

        resolve(x)

    }

}

class MyPromise {

    // 接收一个 执行器

    // new Promise的时候,执行器立即执行,

    // 执行的时候根据指定函数执行

    // 并且程序报错的情况下

    constructor(executor) {

        this.status = STATUS_PENDING;

        this.value = undefined;

        this.reason = undefined;



        // 这里的两个数据,相当于订阅者的篮子,then相当于订阅者,接收到发布者的函数,保存在篮子里

        this.onFulfilledCallBacks = [];

        this.onRejectCallBacks = [];

        try {

            // 这里将传入的resolve和reject变为类中的调用的话。

            // (resolve, reject) => {

            //     resolve("then链式调用");=>this.resolve(then链式调用)

            // }



            executor(this.resolve, this.reject);

        } catch (error) {

            //  报错的话直接将错误原因作为reason

            this.reject(error);

        }

    }

    // 这里为啥使用箭头函数而不是resolve(){}

    // 这是因为上面的executor调用的时候,resolve中的this其实是undefined

    // executor单独调用了resolve/reject 这时,这两个方法存在于执行是的环境,this不再指向实例

    // 箭头函数内部的this总是指向定义时所在的对象

    resolve = (value) => {

        // 判断状态是不是

        if (this.status === STATUS_PENDING) {

            console.log("执行resolve");

            // 这里接收传进来的结果

            this.value = value;

            this.status = STATUS_FULFILLED;

            this.onFulfilledCallBacks.forEach((fn) => {

                fn();

            });

        }

    };

    reject = (reason) => {

        if (this.status === STATUS_PENDING) {

            console.log("执行reject");

            // 这里接收传进来的错误的结果

            this.reason = reason;

            this.status = STATUS_REJECTED;

            // 这里相当于发布的动作

            this.onRejectCallBacks.forEach((fn) => {

                fn();

            });

        }

    };



    then(onFulfilled, onReject) {

        onFulfilled =

            typeof onFulfilled === "function" ? onFulfilled : (value) => value;

        onReject = typeof onReject === "function" ? onReject : (reason) => reason;

        console.log("执行then时的状态: ", this.status);

        let promise2 = new MyPromise((resolve, reject) => {

            if (this.status === STATUS_FULFILLED) {

                // 这个地方使用settimeout的目的是获取到promise2。因为setTimeout是异步的,

                // 会等到赋值给promise2结束后才执行,

                // 这里的resolvePromise的作用是为了区分x是普通值还是新的promise还是函数

                // 如果直接resolve(x)的话会导致,输出的是[object Object] res====,并不是想要的值

                setTimeout(() => {

                    // 这里try进行了捕获异常,在最外面的executor不是进行了捕获了?

                    // 这是因为异步里面的方法不会被最外层的那个捕获到

                    try {

                        console.log("执行 onFulfilled");

                        //   这里的x是啥? 是then中回调的return的返回值

                        let x = onFulfilled(this.value);

                        resolvePromise(promise2, x, resolve, reject);

                    } catch (e) {

                        reject(e);

                    }

                }, 0);

            }

            if (this.status === STATUS_REJECTED) {

                setTimeout(() => {

                    try {

                        console.log("执行 onReject");

                        let x = onReject(this.reason);

                        resolvePromise(promise2, x, resolve, reject);

                    } catch (e) {

                        reject(e);

                    }

                }, 0);

            }

            if (this.status === STATUS_PENDING) {

                this.onFulfilledCallBacks.push(() =>

                    setTimeout(() => {

                        try {

                            let x = onFulfilled(this.value);

                            resolvePromise(promise2, x, resolve, reject);

                        } catch (e) {

                            reject(e);

                        }

                    }, 0)

                );

                this.onRejectCallBacks.push(() =>

                    setTimeout(() => {

                        try {

                            let x = onRejected(this.reason);

                            resolvePromise(promise2, x, resolve, reject);

                        } catch (e) {

                            reject(e);

                        }

                    }, 0)

                );

            }

        });



        return promise2;

    }

}



// 下面的函数相当于发布者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值