手写Promise(一)

参考地址:地址。

目录

一,搭建整体框架和添加then方法到Promise原型

二,实现executor执行器,完善resolve和reject函数

三,实现throw抛出异常后置PromiseState = 'no'

四,完善PromiseState只能被修改一次

五,实现then方法对resolved,rejected状态的支持

六,实现then方法对pending状态的支持

七,实现then绑定多个回调函数

八,实现then返回一个Promise对象(由同步任务决定状态)


一,搭建整体框架和添加then方法到Promise原型

function myPromise(executor) {

}
myPromise.prototype.then(solved, rejectd);

二,实现executor执行器,完善resolve和reject函数

function myPromise(executor) {
    //令executor === (f = (resolve, reject) => resolve('ok'));用于测试的操作,省去了异步操作,resolve, reject函数选择resolve执行
    /*置初始状态*/
    this.PromiseState = 'waiting';
    /*置初始结果*/
    this.PromiseResult = null;
    /*让ins指向实例对象*/
    const ins = this;
    /*实现resolve函数,将异步操作的结果给PromiseResult*/
    function resolve(data) {
        /*改变实例对象的状态*/
        ins.PromiseState = 'yes';
        ins.PromiseResult = data;
    };

    /*实现reject函数*/
    function reject(data) {
        ins.PromiseState = 'no';
        ins.PromiseResult = data;
    };

    /*同步调用执行器,执行传进来的任务,executor被主线程执行后将异步操作放入事件队列*/
    executor(resolve, reject);
    //在这里声明resolve, reject这两个变量,根据业务逻辑选择必须resolve, reject二选一执行,将结果交给resolve, reject即可。
}
myPromise.prototype.then = function(onresolved, onrejectd) {

};

};

三,实现throw抛出异常后置PromiseState = 'no'

        我这个例子写的是no,官方的是rejected。因为只有executor执行出了问题才会异常(貌似只有executor可以执行),所以将executor放入trycatch中。

//单独的解决方法
try {
        executor(resolve, reject);
    } catch (error) {
        reject(error);
    }

四,完善PromiseState只能被修改一次

        解决方法如下:

    function resolve(data) {
        /*改变实例对象的状态*/
        if (ins.PromiseState == 'waiting') {
            ins.PromiseState = 'yes';
        }
        ins.PromiseResult = data;
    };

    /*实现reject函数*/
    function reject(data) {
        if (ins.PromiseState == 'waiting') {
            ins.PromiseState = 'no';
        }
        ins.PromiseResult = data;
    };

五,实现then方法对resolved,rejected状态的支持

        实现方法如下。本例使用yes和no代替。

myPromise.prototype.then = function(onresolved, onrejectd) {
    if (this.PromiseState == 'yes') {
        onresolved(this.PromiseResult); //将实例对象的结果传给回调函数进行处理
    }
    if (this.PromiseState == 'no') {
        onrejectd(this.PromiseResult);
    }
};

六,实现then方法对pending状态的支持

        本例以waiting为例。处于pending的状态大都是因为执行器中放了一个耗时的异步操作,一直没有调用resolve, reject这两个函数,导致状态一直为pending。

        但是then方法的作为参数的两个回调方法只能处理resolved和rejected状态。而且then方法不可能给pending状态添加回调函数,因为对pending状态进行处理会让主线程挂起,这是不可行的。

        另外,如果主线程在还是pending状态时就执行到then方法,会将then方法丢进事件队列(微任务队列),然后接着运行下面的代码,在这之后如果状态改变该如何处理需要被解决。

        解决方法就是:将resolved和rejected状态对应的回调函数进行保存,等到状态变化之后再执行。

function myPromise(executor) {
    //令executor === (f = (resolve, reject) => resolve('ok'));用于测试的操作,省去了异步操作,resolve, reject函数选择resolve执行
    /*置初始状态*/
    this.PromiseState = 'waiting';
    /*置初始结果*/
    this.PromiseResult = null;
    /*让ins指向实例对象*/
    const ins = this;
    /*保存当前实例对象的两个回调函数*/
    ins.callback = {};

    /*实现resolve函数,将异步操作的结果给PromiseResult*/
    function resolve(data) {
        /*改变实例对象的状态*/
        if (ins.PromiseState == 'waiting') {
            ins.PromiseState = 'yes';
        }
        ins.PromiseResult = data;
        /*对是否为waiting状态进行判断,如果主线程经过then的时候还是waiting,则具有solved,rejected两个属性*/
        if (ins.callback.solved) {
            ins.callback.solved(data);
        }
    };

    /*实现reject函数*/
    function reject(data) {
        if (ins.PromiseState == 'waiting') {
            ins.PromiseState = 'no';
        }
        ins.PromiseResult = data;
        /*对是否为waiting状态进行判断,如果主线程经过then的时候还是waiting,则具有solved,rejected两个属性*/
        if (ins.callback.rejected) {
            ins.callback.rejected(data);
        }
    };

    /*同步调用执行器,执行传进来的任务,executor被主线程执行后将异步操作放入事件队列*/
    try {
        //在这里声明resolve, reject这两个变量,根据业务逻辑选择必须resolve, reject二选一执行,将结果交给resolve, reject即可。
        executor(resolve, reject);
    } catch (error) {
        reject(error);
    }
}
myPromise.prototype.then = function(solved, rejected) {
    //solved, rejected分别对应成功和失败的回调函数。
    if (this.PromiseState == 'yes') {
        solved(this.PromiseResult); //将实例对象的结果传给回调函数进行处理
    }
    if (this.PromiseState == 'no') {
        rejected(this.PromiseResult);
    }
    //当主线程执行到then方法的时候还是pending状态的话就将两个回调函数保存,主线程放弃了他们,程序员不能
    if (this.PromiseState == 'waiting') {
        this.callbacks = {
            solved,
            rejected
        }
    }
};

七,实现then绑定多个回调函数

        多次给then绑定不同的回调函数,会丢失对前面的联系,只会绑定到最后一次的回调函数。当多次使用:p.then时,把这些回调函数都保存起来,然后依次调用即可。

function myPromise(executor) {
    //令executor === (f = (resolve, reject) => resolve('ok'));用于测试的操作,省去了异步操作,resolve, reject函数选择resolve执行
    /*置初始状态*/
    this.PromiseState = 'waiting';
    /*置初始结果*/
    this.PromiseResult = null;
    /*让ins指向实例对象*/
    const ins = this;
    /*保存当前实例对象的两个回调函数*/
    ins.callbacks = [];

    /*实现resolve函数,将异步操作的结果给PromiseResult*/
    function resolve(data) {
        /*改变实例对象的状态*/
        if (ins.PromiseState == 'waiting') {
            ins.PromiseState = 'yes';
        }
        ins.PromiseResult = data;
        /*对多个then传进来的回调函数依次执行*/
        ins.callbacks.forEach((item) => item.solved(data))
    };

    /*实现reject函数*/
    function reject(data) {
        if (ins.PromiseState == 'waiting') {
            ins.PromiseState = 'no';
        }
        ins.PromiseResult = data;
        /*对多个then传进来的回调函数依次执行*/
        ins.callbacks.forEach((item) => item.rejected(data))
    };

    /*同步调用执行器,执行传进来的任务,executor被主线程执行后将异步操作放入事件队列*/
    try {
        //在这里声明resolve, reject这两个变量,根据业务逻辑选择必须resolve, reject二选一执行,将结果交给resolve, reject即可。
        executor(resolve, reject);
    } catch (error) {
        reject(error);
    }

}
myPromise.prototype.then = function(solved, rejected) {
    //solved, rejected分别对应成功和失败的回调函数。
    if (this.PromiseState == 'yes') {
        solved(this.PromiseResult); //将实例对象的结果传给回调函数进行处理
    }
    if (this.PromiseState == 'no') {
        rejected(this.PromiseResult);
    }
    //当主线程执行到then方法的时候还是pending状态的话就将两个回调函数保存,主线程放弃了他们,程序员不能
    if (this.PromiseState == 'waiting') {
        this.callbacks.push({
            solved,
            rejected
        });
    }


};

八,实现then返回一个Promise对象(由同步任务决定状态)

        由原生Promise类可知,then方法返回一个Promise对象,且返回结果由回调函数的执行结果决定。如下图。 

function myPromise(executor) {
    //令executor === (f = (resolve, reject) => resolve('ok'));用于测试的操作,省去了异步操作,resolve, reject函数选择resolve执行
    /*置初始状态*/
    this.PromiseState = 'waiting';
    /*置初始结果*/
    this.PromiseResult = null;
    /*让ins指向实例对象*/
    const ins = this;
    /*保存当前实例对象的两个回调函数*/
    ins.callbacks = [];

    /*实现resolve函数,将异步操作的结果给PromiseResult*/
    function resolve(data) {
        /*改变实例对象的状态*/
        if (ins.PromiseState == 'waiting') {
            ins.PromiseState = 'yes';
        }
        ins.PromiseResult = data;
        /*对多个then传进来的回调函数依次执行*/
        ins.callbacks.forEach((item) => item.solved(data))
    };

    /*实现reject函数*/
    function reject(data) {
        if (ins.PromiseState == 'waiting') {
            ins.PromiseState = 'no';
        }
        ins.PromiseResult = data;
        /*对多个then传进来的回调函数依次执行*/
        ins.callbacks.forEach((item) => item.rejected(data))
    };

    /*同步调用执行器,执行传进来的任务,executor被主线程执行后将异步操作放入事件队列*/
    try {
        //在这里声明resolve, reject这两个变量,根据业务逻辑选择必须resolve, reject二选一执行,将结果交给resolve, reject即可。
        executor(resolve, reject);
    } catch (error) {
        reject(error);
    }

}
myPromise.prototype.then = function(solved, rejected) {
    task = (resolve, reject) => {
        if (this.PromiseState == 'yes') {
            //成功状态下记录结果,根据结果决定执行resolve还是reject
            let result = solved(this.PromiseResult);
            try {
                if (result instanceof myPromise) {
                    //假如是myPromise还需要细分
                    result.then(
                        v => { resolve(v) },
                        err => { reject(err) }
                    )
                } else {
                    //不是mypromise的实例,则直接使用resolve函数返回result
                    resolve(result);
                }
            } catch (error) {
                reject(error);
            }
        }
        if (this.PromiseState == 'no') {
            rejected(this.PromiseResult);
        }
        if (this.PromiseState == 'waiting') {
            this.callbacks.push({
                solved,
                rejected
            });
        }
    }
    return new myPromise(task); //then方法需要返回一个myPromise实例,在这里返回
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值