手写Promise

Promise语法

new Promise( function(resolve, reject) { /* executor */
    // 执行代码 需要指明resolve与reject的回调位置
});

executor是带有resolve和reject两个参数的函数。Promise构造函数执行时立即调用executor函数,resolve和reject两个函数作为参数传递给executor。resolve和reject函数被调用时,分别将promise的状态改为完成fulfilled或失败rejected。executor内部通常会执行一些异步操作,一旦异步操作执行完毕,要么调用resolve函数来将promise状态改成fulfilled,要么调用reject函数将promise的状态改为rejected。如果在executor函数中抛出一个错误,那么该promise状态为rejected,executor函数的返回值被忽略。

Promise状态

pending: 初始状态,既不是成功,也不是失败状态。
fulfilled: 意味着操作成功完成。
rejected: 意味着操作失败。

Promise对象只有从pending变为fulfilled和从pending变为rejected的状态改变。只要处于fulfilled和rejected,状态就不会再变了。

实现

function _Promise(fn){
    this.status = "pending";    //定义属性存储状态 //赋予初始状态pending
    this.value = null;  //resolve的value
    this.reason = null; //reject的reason
    this.onFulfilled = [];  //存储then方法中注册的第一个回调函数
    this.onReject = [];     //存储then方法中注册的第二个回调函数

    //事件处理函数
    let handler = funct => {
        if(typeof(funct) === "function"){//如果是函数的话才执行
            if(this.status === "fulfilled") //执行并传递value
                funct(this.value);
            if(this.status === "rejected")  //执行并传递rejected
                funct(this.reason);

        }
    }

    //实现resolve回调
    let resolve = value => {
        this.status = "fulfilled";  //设置状态
        this.value = value;     //得到结果
        if(value instanceof _Promise){//判断返回的值是否为Promise实例
            value.onFulfilled = this.onFulfilled;
            return value;
        }
        setTimeout(() => { //使用setTimeout是为了将回调函数置于任务对列,不阻塞主线程,异步执行,实际promise的回调是置于微队列的,而setTimeout的回调是置于宏队列
            try{
                this.onFulfilled.forEach(handler);
            }catch(e){
                console.log(`Error in promise:${e}`);
                reject(e);  //reject
            }
        },0);
    }

    //实现rejected
    let reject = reason => {
        this.status = "rejected";   //设置状态
        this.reason = reason;
        setTimeout(() => {  //置于任务队列
            try{
                this.onReject.forEach(handler); //交于事件处理
            }catch(e){
                console.error(`Error in promise:${e}`); //打印异常
            }
        },0);
    }

    fn(resolve,reject); // 执行
}

//定义then
//value接收上层结果---function处理自身逻辑 ---return传递到下层
_Promise.prototype.then = function(onFulfilled,onRejected){
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v; //转换为函数
    onRejected = typeof onRejected === 'function' ? onRejected : r => r;    //转换为函数
    return new _Promise((resolve,reject) => {//返回一个新的_Promise
        this.onFulfilled.push((value) => {  //将回调函数置于onFullfilled
            resolve(onFulfilled(value));    //执行并传递
        });
        this.onReject.push((value) => {//将回调函数置于onReject
            reject(onRejected(value));  //执行并传递
        });
    })
}

//测试
var promise = new _Promise(function(resolve,reject){
    var rand = Math.random() * 2;
     setTimeout(function(){
        if(rand < 1) resolve(rand);
        else reject(rand);
    },1000)
})
promise.then((rand) => {
   console.log("resolve",rand); // resolve回调执行
}, (rand) => {
   console.log("reject",rand); // reject回调执行
}).then(function(){ // resolve后继续执行
   return new _Promise(function(resolve,reject){
    var rand = Math.random() * 2;
     setTimeout(function(){
        resolve(rand);
    },1000)
})
}).then(function(num){ // resolve后继续执行
   console.log(num,"继续执行并接收参数");
   return 1;
}).then(function(num){
   console.log(num,"继续执行并接收参数");
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值