手写Promise(二)——then方法的添加

then方法的添加

最终代码放在最下面

在有了构造函数的框架下,最重要的then方法应该怎么添加呢?

最好的方法当然是添加到原型里了!

分析内置的Promise的then方法,他接受两个参数,所以我们可以写成这样:

// 添加then方法
Promise.prototype.then = function (onResolve, onRejected) {
    // 通过实例的PromiseState判断执行哪一个参数
    if (this.PromiseState === 'fulfilled') {
        // 方法接受一个参数,即PromiseResult
        onResolve(this.PromiseResult);
    }
    if (this.PromiseState === 'rejected') {
        // 方法接受一个参数,即PromiseResult
        onRejected(this.PromiseResult);
    }

}

如果Promise中执行同步代码好像没有问题,当时通过执行的是异步代码就有问题了,但我们执行下面的代码时:
在这里插入图片描述
在这里插入图片描述
我们可以看到,实例的promise的属性并没有被改变,所以我们还没有实现异步的效果。

所以我们要在then方法中多加一个状态判断(pending),在pending中,我们需要存下来回调函数(onResolve,onRejected),在状态发送改变的时候再调用它,所以我们要在构造函数中添加一个callback用来存储回调函数,将处于pending状态中的then中方法存进去,只有状态发生改变才能调用对应的方法,所以要将callback中的方法在resolve或reject中调用

this.callback={};
-----------------
 this.callback={
            onRejected,
            onResolve,
 } 这里使用来简写
 -----------------
 在对应的resolve和reject中调用callback对应的方法
// 构造声明函数
function Promise(executor) {
    // 添加属性
    this.PromiseState = 'pending'; // 默认初始为pending
    this.PromiseResult = null; // 初始为空
    this.callback={};
    // 保存原来的this
    const self = this;
    function resolve(data) {
        // 判断状态是否被修改
        if (self.PromiseState !== 'pending') return;

        // 修改对象结果
        self.PromiseResult = data;
        // 修改对象状态
        self.PromiseState = 'fulfilled';
        
        // 执行回调函数,该函数接受的参数为PromiseResult
        if(self.callback.onResolve){
            self.callback.onResolve(data);
        }
    }
    function reject(data) {
        // 判断状态是否被修改
        if (self.PromiseState !== 'pending') return;
        // 修改对象结果
        self.PromiseResult = data;
        // 修改对象状态
        self.PromiseState = 'rejected';
         // 执行回调函数,该函数接受的参数为PromiseResult
         if(self.callback.onRejected){
            self.callback.onRejected(data);
        }
    }

    try {
        // 同步调用 执行器函数
        executor(resolve, reject);
    } catch (e) {
        reject(e);// 因为抛出错误的状态是rejected,所以直接在调用rejected就行了
    }

}

// 添加then方法
Promise.prototype.then = function (onResolve, onRejected) {
    // 通过实例的PromiseState判断执行哪一个参数
    if (this.PromiseState === 'fulfilled') {
        // 方法接受一个参数,即PromiseResult
        onResolve(this.PromiseResult);
    }
    if (this.PromiseState === 'rejected') {
        // 方法接受一个参数,即PromiseResult
        onRejected(this.PromiseResult);
    }
    if (this.PromiseState === 'pending') {
        // 重要!!! 保存回调函数
        this.callback={
            onRejected,
            onResolve
        }
        
    }

}

但是这种方法并不是最好的,因为当出现多次调用then的时候,下面的then中的回调函数会覆盖掉上面then的回调函数,所以我们改用数组!如何循环执行数组的回调函数

// 构造声明函数
function Promise(executor) {
    // 添加属性
    this.PromiseState = 'pending'; // 默认初始为pending
    this.PromiseResult = null; // 初始为空
    this.callback=[];
    // 保存原来的this
    const self = this;
    function resolve(data) {
        // 判断状态是否被修改
        if (self.PromiseState !== 'pending') return;

        // 修改对象结果
        self.PromiseResult = data;
        // 修改对象状态
        self.PromiseState = 'fulfilled';
        
        // 执行回调函数,该函数接受的参数为PromiseResult
        self.callback.forEach(item=>{
            item.onResolved(data);
        })
    }
    function reject(data) {
        // 判断状态是否被修改
        if (self.PromiseState !== 'pending') return;
        // 修改对象结果
        self.PromiseResult = data;
        // 修改对象状态
        self.PromiseState = 'rejected';
         // 执行回调函数,该函数接受的参数为PromiseResult
        self.callback.forEach(item=>{
            item.onRejected(data);
        })
    }

    try {
        // 同步调用 执行器函数
        executor(resolve, reject);
    } catch (e) {
        reject(e);// 因为抛出错误的状态是rejected,所以直接在调用rejected就行了
    }

}

// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
    // 通过实例的PromiseState判断执行哪一个参数
    if (this.PromiseState === 'fulfilled') {
        // 方法接受一个参数,即PromiseResult
        onResolved(this.PromiseResult);
    }
    if (this.PromiseState === 'rejected') {
        // 方法接受一个参数,即PromiseResult
        onRejected(this.PromiseResult);
    }
    if (this.PromiseState === 'pending') {
        // 重要!!! 保存回调函数
        this.callback.push({
            onRejected,
            onResolved
        })
        
    }

}

在内置的Promise中,调用then方法后返回的是一个Promise对象,所以我们手写的then方法要返回一个Promise对象,并且要注意的是:如果在then有返回,还需要判断,1.如果返回的是Promise对象,根据返回的Promise的状态来决定then方法返回的Promise对象的状态2. 如果返回的是非Promise对象,then方法放回的Promise对象状态为fulfilled

// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
    
    // 返回一个Promise对象
    return new Promise((resolve, reject) => {
        // 通过实例的PromiseState判断执行哪一个参数
        if (this.PromiseState === 'fulfilled') {
            // 方法接受一个参数,即PromiseResult
            // 接收一下回调函数的结果
            let result = onResolved(this.PromiseResult);
            if (result instanceof Promise) {
                // 如果回调函数返回的是一个Promise对象,那么就根据它的状态来决定我将要返回出去的Promise对象的状态
                result.then(v => {
                    // 如果返回的是resolve状态
                    resolve(v)
                }, r => {
                    resolve(r);
                })
            } else {
                // 如果不是一个Promise对象
                resolve(result);
            }
        }
        if (this.PromiseState === 'rejected') {
            // 方法接受一个参数,即PromiseResult
            onRejected(this.PromiseResult);
        }
        if (this.PromiseState === 'pending') {
            // 重要!!! 保存回调函数
            this.callback.push({
                onRejected,
                onResolved
            })

        }
    })


}

状态为reject和pending的处理情况相同,所以封装成一个函数 callback,但是要注意this指向和异常捕获的问题

 // 封装函数 callback
        function callback(type){
            try {
                let result = type(self.PromiseResult);
                if(result instanceof  Promise){
                    result.then(v=>resolve(v),r=>reject(r))
                }else{
                    resolve(result)
                }
            } catch (e) {
                reject(e)
            }
        }

最终代码

// 构造声明函数
function Promise(executor) {
    // 添加属性
    this.PromiseState = 'pending'; // 默认初始为pending
    this.PromiseResult = null; // 初始为空
    this.callback = [];
    // 保存原来的this
    const self = this;
    function resolve(data) {
        // 判断状态是否被修改
        if (self.PromiseState !== 'pending') return;

        // 修改对象结果
        self.PromiseResult = data;
        // 修改对象状态
        self.PromiseState = 'fulfilled';

        // 执行回调函数,该函数接受的参数为PromiseResult
        self.callback.forEach(item => {
            item.onResolved(data);
        })
    }
    function reject(data) {
        // 判断状态是否被修改
        if (self.PromiseState !== 'pending') return;
        // 修改对象结果
        self.PromiseResult = data;
        // 修改对象状态
        self.PromiseState = 'rejected';
        // 执行回调函数,该函数接受的参数为PromiseResult
        self.callback.forEach(item => {
            item.onRejected(data);
        })
    }

    try {
        // 同步调用 执行器函数
        executor(resolve, reject);
    } catch (e) {
        reject(e);// 因为抛出错误的状态是rejected,所以直接在调用rejected就行了
    }

}

// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
    const self=this
    // 返回一个Promise对象
    return new Promise((resolve, reject) => {
        // 封装一个函数 
        function callback(type){
            try{
                let result=type(self.PromiseResult);
                if (result instanceof Promise) {
                    // 如果回调函数返回的是一个Promise对象,那么就根据它的状态来决定我将要返回出去的Promise对象的状态
                    result.then(v => {
                        // 如果返回的是resolve状态
                        resolve(v)
                    }, r => {
                        resolve(r);
                    })
                } else {
                    // 如果不是一个Promise对象
                    resolve(result);
                }
            }catch(e){
                reject(e);
            }
        }
        // 通过实例的PromiseState判断执行哪一个参数
        if (this.PromiseState === 'fulfilled') {
            // 方法接受一个参数,即PromiseResult
            // 接收一下回调函数的结果
            let result = onResolved(this.PromiseResult);
            if (result instanceof Promise) {
                // 如果回调函数返回的是一个Promise对象,那么就根据它的状态来决定我将要返回出去的Promise对象的状态
                result.then(v => {
                    // 如果返回的是resolve状态
                    resolve(v)
                }, r => {
                    resolve(r);
                })
            } else {
                // 如果不是一个Promise对象
                resolve(result);
            }
        }
        if (this.PromiseState === 'rejected') {
            // 方法接受一个参数,即PromiseResult
            onRejected(this.PromiseResult);
            callback(onRejected)
        }
        if (this.PromiseState === 'pending') {
            // 重要!!! 保存回调函数
            this.callback.push({
                onResolved: function () {
                 callback(onResolved);

                },
                onRejected: function () {
                    callback(onRejected);

                }
            })

        }
    })


}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

传说中的懿痕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值