唯心主义蠢货的[js知识总结] 手写一个promise

promise

用法分析

在这里插入图片描述

流程分析
  • promise通过一个接收一个函数进行实例化
  • 此函数接收两个参数,一个为fulfill时进行的处理,一个为reject时进行的处理
  • 当exector函数在promise内部进行执行时,修改promise的value和status
  • 在then和catch中,根据status进行条件判断
关于优化的点
  • exector为异步调用时
  • 如何实现then的链式调用

代码基本实现

  • promise接收一个exector,并在内部进行value和status的改变 在这里插入图片描述

  • then进行resolve的实现
    在这里插入图片描述

  • catch进行reject的实现
    在这里插入图片描述

代码优化

关于异步

当出现异步操作时,即promise先对exector内部逻辑进行事件注册,然后对then和catch进行执行,当exector内部需要执行时再进行执行,也即需要先对then和catch对应的事件进行保留,再根据exector的改变进行调用

  • 在promise内声明两个操作数组
    在这里插入图片描述

  • 在then中加入pending状态下,将操作事件压入的分支

  • 在promise中当status改变时,对操作数组内的事件进行执行

关于链式操作
  • 链式操作的关键在于在操作时,返回一个promise

  • promise的exector函数,为对当前then传入的fulfulled和rejected函数的处理
    1570421403141.png"

  • promise的value和status值,为上一步即fulfulled和rejected的返回值

    • 如果返回值为非promise类型,则通过resolve状态改变函数,将此返回值作为参数传入

    • 如果返回值为promise类型,则通过x.then(resolve,reject) 对其内部的值进行改变(由于resolve和reject的this都对应着返回值promise,x内部的操作即对返回promise的value和status的改变)

    • 如果出现错误,则也将其作为下一个promise的成功resolve的参数进行传递

代码

function promise( exector ) {
        let _this = this;
        this.value = null; // 处理值
        this.status = 'pending'; //当前状态
        this.reason = null; // 失败原因
        this.onFulfilledCallback = []; // resolve处理数组
        this.onRejectCallback = []; // reject处理数组
        //当且仅当 status为pending时 状态才可以改变  即一旦成功或失败 则不允许改变状态
        //resolve函数  改变value  改变状态
        function resolve( value ) {
            if (_this.status == 'pending') {
                _this.value = value;
                _this.status = 'resolve';
                _this.onFulfilledCallback.forEach(fn => {
                    fn(_this.value); // 根据函数注册的顺序执行
                });
            }
        }

        // reject函数  改变reason  改变状态
        function reject( reason ) {
            if (_this.status == 'pending') {
                _this.reason = reason;
                _this.status = 'reject';
                _this.onRejectCallback.forEach(fn => {
                    fn(_this.reason);
                });
            }
        }

        try {
            exector(resolve, reject);  //执行  进行状态的改变
        } catch ( e ) {
            reject(e);  // 直接跳到reject状态
        }
    }

    promise.prototype.then = function ( onFulfilled, onRejected ) {
        let _this = this;
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function ( value ) { };  // 判断是否为函数
        onRejected = typeof onRejected === 'function' ? onRejected : function ( reason ) {  };
        if (_this.status == 'resolve') {
            return new promise(( resolve, reject ) => {
                try {
                    let x = onFulfilled(_this.value);//处理这一步的操作
                    if( x instanceof promise){  //但当前返回值为promise时
                        x.then(resolve,reject);
                        //因为resolve和reject都指向外部this,所以在x中改变value和status即对外部进行改变
                    }
                    else{
                        resolve(x);  // 改变返回promise的value和status
                    }
                }
                catch ( e ) {
                    reject(e);
                }
            });
        }
        if (_this.status == 'reject') {
            return new promise(( resolve, reject ) => {
                try {
                    let x =onRejected(_this.value);
                    if(x instanceof promise){
                        x.then(resolve,reject);  
                    }
                    else{
                        resolve(x);
                    }
                }
                catch ( e ) {
                    reject(e);
                }
            });
        }
        if (_this.status == 'pending') {
            return new promise(( resolve, reject ) => {
                _this.onFulfilledCallback.push(() =>{
                    let x = onFulfilled(_this.value);
                    if( x instanceof  promise){
                        x.then(resolve,reject);
                    }else{
                        resolve(x);
                    }
                });
                _this.onRejectCallback.push( () =>{
                    let x = onRejected(_this.reason);
                    if(x instanceof promise){
                        x.then(resolve,reject);
                    }else{
                        resolve(x);
                    }
                });
            });
        }
    };
    promise.prototype.catch = function ( error ) {
        return this.then(null, error);
    };

    function test( resolve, reject ) {
        let i = Math.random() * 10;
        setTimeout(function () {
            if (i > 5) {
                resolve(i);
            } else {
                reject(i);
            }
            ;
        }, 500);
        console.log('123456');
    }

    function test2( x ) {
        let i = Math.random() * 100;
        return new promise(function ( resolve,reject ) {
            console.log("略略略"+x);
            resolve(x+1);
        });
    }

    let p = new promise(test);
    // p.then(function ( value ) {
    //     console.log('resolve' + value);
    //     return " resolve"+value;
    // },function ( error ) {
    //     console.log('error' + error);
    //     return " error"+error;
    // }).then(function ( value ) {
    //     console.log('resolve' + value);
    // }).catch(function ( error ) {
    //     console.log('error' + error);
    // });

    p.then(test2).then(test2);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值