0818-JS实现Promise对象

利用JS实现Promise对象

首先新建类MyPromise,并声明静态常量PENDINGFUFILLEDREJECTED表示promise的状态,exector函数带有resolvereject两个函数参数,MyPromise执行构造函数时立即调用;调用resolvereject函数时,分别将promise状态改为fulfilledrejected

代码如下:

MyPromise类:

class MyPromise{
    static PENDING = 'pending';
    static FUFILLED = 'fufilled';
    static REJECTED = 'rejected';

    constructor(executor){
    this.status = MyPromise.PENDING;
    this.value = null;
    executor(this.resolve.bind(this), this.reject.bind(this));
    }

    resolve(value){
        this.status = MyPromise.FUFILLED;
        this.value = value;
    }

    reject(reason){
        this.status = MyPromise.REJECTED;
        this.value = reason;
    }
    }

调用MyPromise

let mypromise = new MyPromise((resolve, reject) => {
  resolve("已解决");
  reject("拒绝");
});
console.log(mypromise)

此时,在mypromise实例中,promise的状态在改为成功后,依旧可以改为失败

只需在resolve()reject()中分别添加状态判断即可

resolve(value){
        if(this.status == MyPromise.PENDING){
            this.status = MyPromise.FUFILLED;
            this.value = value;
        }
    }
    
reject(reason){
    if(this.status == MyPromise.PENDING){
        this.status = MyPromise.REJECTED;
        this.value = reason;
    }

在promise中,如果在executor函数中抛出一个错误,promise的状态也应是rejected,返回值被忽略。将构造函数中的executor()函数加上异常捕获,并修改状态

executor(this.resolve.bind(this), this.reject.bind(this));

//改为:

try {
    executor(this.resolve.bind(this), this.reject.bind(this));
    }catch(error) {
        this.reject(error);
    }

接着实现then函数,在MyPromise函数中添加then方法

then(onFulfilled, onRejected){
    if(typeof onFulfilled !== "function"){
        onFulfilled = () => {};
    }
    if(typeof onRejected !== "function"){
        onRejected = () => {};
    }
//两个if防止 当 .then() 中只写处理成功状态或失败状态函数时报错
    if(this.status == MyPromise.FUFILLED){
        onFulfilled(this.value);
    }
    if(this.status == MyPromise.REJECTED){
        onRejected(this.value)
    }
//两个if 当promise中不处理时,即状态为pending时,不执行
}

加入异常捕获,放入setTimeout()中,实现异步

if(this.status == MyPromise.FUFILLED){
        onFulfilled(this.value);
    }
    if(this.status == MyPromise.REJECTED){
        onRejected(this.value)
    }
//改后
if(this.status == MyPromise.FUFILLED){
    setTimeout( () => {  //实现同步代码比promise中的先执行
        try {
            onFulfilled(this.value);
        } catch (error) {
            onRejected(error);
        }
    });
}
if(this.status == MyPromise.REJECTED){
    setTimeout( () =>{
        try {
            onRejected(this.value);
        } catch (error) {
            onRejected(error);
        }
    });
}

当调用如下时

let mypromise = new MyPromise((resolve, reject) => {
  setTimeout( () => {
  resolve("已解决");
  },1000);
  // reject("拒绝");
}).then(value => console.log(value), reason => console.log(reason));

此时,由于同步代码执行完毕后,MyPromise的状态延迟1000毫秒改变,因此执行then()函数时,依旧为pengding状态,此时不会执行onFulfilledonRejected函数,由于顺序执行,定时器到时之后promise状态改变,但无法正常输出。

此时在MyPromise类的构造函数中加入this.callbacks = [];,用于盛放onFulfilledonRejected函数,分别在resolve()reject()调用,即可实现

//constructor中加入
this.callbacks = [];

//resolve()和reject()中分别加入
this.callbacks.map(callback => {
    callback.onFulfilled(value);
});

this.callbacks.map(callback => {
    callback.onRejected(value);
});

//在then函数中加入状态判断
if (this.status == MyPromise.PENDING){
    this.callbacks.push({
        onFulfilled,
        onRejected
    });
}

经过上述改动后,调用时,在resolve("已解决");后面加上语句console.log("我先输出");,正常输出顺序为“我先输出”、“已解决”,但此时相反

将上边resolve()reject()中新增的函数分别放进计时器即可

setTimeout(() => {
    this.callbacks.map(callback => {
        callback.onFulfilled(value);
    });
    });

此时还不能进行链式操作,将then()方法中的状态判断及onFulfilledonRejected函数整体刚入一个新的MyPromise中返回并将onFulfilledonRejected函数的返回值分别给resolve()reject()传给下一层then即可实现链式操作

return new MyPromise((resolve,reject) =>{
    if (this.status == MyPromise.PENDING){
        this.callbacks.push({
            onFulfilled: value => {
                try{
                    let result = onFulfilled(value);
                    resolve(result);
                } catch(error) {
                    reject(error);
                }
            },
            onRejected: value => {
                try {
                    let result = onRejected(value);
                    resolve(result);
                } catch (error) {
                    reject(error);
                }
            }
        });
    }

    if(this.status == MyPromise.FUFILLED){
        setTimeout( () => {
            try {
                let result = onFulfilled(this.value);
                resolve(result);
            } catch (error) {
                reject(error);
            }
        });
    }

    if(this.status == MyPromise.REJECTED){
        setTimeout( () =>{
            try {
                let result = onRejected(this.value);
                resolve(result);
            } catch (error) {
                reject(error);
            }
        });
    }
    })

除此之外,原生then还有穿透性,即不对某一层then()进行任何处理,下一层照常可以进行处理

//只需要在此处 给他返回当前的value值即可穿透传递
if(typeof onFulfilled !== "function"){
            onFulfilled = () => this.value;
        }
        if(typeof onRejected !== "function"){
            onRejected = () => this.value;
        }

实现promise.all()函数

static all(promises){
    const values = [];
    return new MyPromise((resolve,reject) => {
        promises.forEach(promise => {
            promise.then(value => {
                values.push(value);
                if(values.length == promises.length){
                    resolve(values)
                }
            }, reason => {
                reject(reason);
            });        
        });
    });
    }

实现promise.race()方法

static race(promises) {
    return new MyPromise((resolve, reject) => {
        promises.forEach(promise => {
            promise.then(value => {
                resolve(value);
            }, reason => {
                reject(reason);
            })
        });
    });
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值