【JS系列】手撕Promise

1.0什么是Promise?

2.0 如何实现一个Promise

2.1 初步实现promise

Promise的特点:

  • 有三种状态,默认是pending,成功为fulfilled,失败为rejected
  • 创建时必须传递一个函数,不然会报错
  • 传递函数中参数是两个回调函数,resolve和reject
  • 状态一旦发生改变就不会发生变化
 class MyPromise{
        //有一个构造器
        constructor(fn) {
            //这个构造器要判断接收进来的是不是一个函数
            if (!this.isFun(fn)){
                throw new Error('这不是一个函数');
            }
            //1.定义默认状态
            this.status = 'pending';
            //2.函数参数fn中有两个回调函数resolve、reject
            //2.1调用resolve就改变status为fulfilled
            this.resolve = (data)=>{
                //状态一旦发生改变就不会在改变,所以在这里判断下是否为默认状态
                if (this.status === 'pending'){
                    this.status ='fulfilled';
                    console.log('fulfilled');
                }
            }
            //2.1调用reject就改变status为rejected
            this.reject = (data)=>{
                //这里的判断是因为status改变了就不能再改变
                if (this.status === 'pending'){
                    this.status = 'rejected';
                    console.log('rejected');
                }
            }
            fn(this.resolve,this.reject);

        }
        //判断fn是是否是一个函数
        isFun(fn){
            return typeof fn === 'function';
        }
    }
    let case = new MyPromise(function (resolve,reject) {
        resolve();
    });
    console.log(case);

输出结果:

//调用resolve()

//调用reject()

 let case = new MyPromise(function (resolve,reject) {
        reject();
    });
    console.log(case);

//重复调用

let a = new MyPromise(function (resolve,reject) {
        resolve();
        reject();
    });
    console.log(a);

//说明status的状态一旦被改变就不能再被改变 

//传入非函数参数:

 let a = new MyPromise([1,2,3]);
    console.log(a);

2.2 实现primose实例的then方法

Promise的特点:

  • 同一个promise对象可以添加多个then监听,状态改变时会按照监听顺序依次执行
  • then方法每次执行完毕会返回一个新的promise对象
  • 上一个Promise对象的then方法可以给返回的新的Promise的then传递参数
  • 无论上一个是在then成功或者失败的回调中传参,都会传递给新的Promise对象then方法中成功的回调
  • 如果上一个传递的是一个Promise对象,那么传给下一个的成功还是失败由传递的Promsie状态决定  
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>手写promise</title>
</head>
<body>
<script>
    class MyPromise{
        //有一个构造器
        constructor(fn) {
            //这个构造器要判断接收进来的是不是一个函数
            if (!this.isFun(fn)){
                throw new Error('这不是一个函数');
            }

            this.status = 'pending';
            //定义两个属性保持resolve和reject中的参数
            this.value = undefined;
            this.fail = undefined;
            //存放成功的数组
            this.onSuccessCallbacks = [];
            //存放失败的数组
            this.onFailCallbacks = [];

            //函数参数中有两个回调参数,resolve和reject
            this.resolve = (data)=>{
                //状态一旦发生改变就不会在改变,所以在这里判断下是否为默认状态
                if (this.status === 'pending'){
                    this.status ='fulfilled';
                    this.value = data;
                    if (this.onSuccessCallbacks){
                        this.onSuccessCallbacks.forEach((fn) =>{
                            fn(this.value)
                        })
                    }
                    // console.log('fulfilled');
                }
            }
            //2.1调用reject就改变status为rejected
            this.reject = (data)=>{
                //这里的判断是因为status改变了就不能再改变
                if (this.status === 'pending'){
                    this.status = 'rejected';
                    this.fail = data;
                    if (this.onFailCallbacks){
                        this.onFailCallbacks.forEach((fn)=>{
                            fn(this.fail);
                        })
                    }
                    // console.log('rejected');
                }
            }
            fn(this.resolve,this.reject);

        }
        //then方法、有两个参数、成功回调和失败回调
        then(onSuccess,onFail){
            //每次执行then方法都会返回一个新的Promise实例
            return new MyPromise((nextSuccess,nextFail)=>{
                //成功或者失败的回调也必须是个函数
                if (this.isFun(onSuccess)){
                    //只有状态改变才会执行
                    if (this.status === 'fulfilled'){
                        //因为then中可以拿到resolve和reject中传递的参数
                        //then中也可以return一个Promise
                        //那么传给下一个的成功还是失败由传递的promise状态决定
                        let res = onSuccess(this.value);
                        //判断返回的是否是个promise对象
                        if(res instanceof  MyPromise){
                            res.then(nextSuccess,nextFail);
                        }else if (res!== undefined){
                            nextSuccess(res);
                        }else {
                            nextSuccess();
                        }
                    }
                }

                if (this.isFun(onFail)){
                    if (this.status === 'rejected'){
                        let res = onFail(this.fail);
                        if (res instanceof MyPromise){
                            res.then(nextSuccess,nextFail);
                        }else if (res !== undefined){
                            nextSuccess(res);
                        }else {
                            nextFail();
                        }
                    }
                }

                //解决延迟回调问题,因为可能你会在promise中放一个定时器
                if (this.status === 'pending'){
                    if (this.isFun(onSuccess)){
                        //将then中要执行的回调都保持到一个数组中,当状态改变时依次执行
                        this.onFailCallbacks.push(()=>{
                            let res = onSuccess(this.value);
                            if (res instanceof MyPromise){
                                res.then(nextSuccess,nextFail)
                            }else if (res!==undefined){
                                nextSuccess(res);
                            }else {
                                nextSuccess();
                            }
                        })
                    }
                }
                if (this.isFun(onFail)){
                    this.onFailCallbacks.push(()=>{
                        let res = onFail(this.fail);
                        if (res instanceof MyPromise){
                            res.then(nextSuccess,nextFail)
                        }else if(res !==undefined){
                            nextSuccess(res);
                        }else{
                                nextFail();
                        }

                    })
                }
            })
        }

        //判断fn是是否是一个函数
        isFun(fn){
            return typeof fn === 'function';
        }
    }
    let a = new MyPromise(function (resolve,reject) {
        setTimeout(()=>{
            //resolve('xyz')
            reject('xyz');
        },1000)
        console.log('执行了');
    });
    a.then(function (data) {
        console.log(data,'success');
    },function (data) {
        console.log(data,'fail');
    })
</script>

</body>
</html>

持续更新……

猜你喜欢

转载自blog.csdn.net/weixin_41950078/article/details/115464637