美文网首页
手撕Promise真面目(手写 promise 代码没有那么难)

手撕Promise真面目(手写 promise 代码没有那么难)

作者: 酷酷的凯先生 | 来源:发表于2020-11-03 09:08 被阅读0次

    咱们书接上文( 点我查看 ),继续咱们的手写 Promise

    # 第三步: Promise .then() / catch() 的实现

    /**
     * @func Promise 原型对象中的 then()
     * @param onResoled 成功的回调函数
     * @param onRejected 失败的回调函数
     * @returns  返回一个新的 Promise 对象
    *  @returns 返回 Promise  的结果由 onResolved / onRejected 执行结果决定
     */
    Promise.prototype.then = function(onResolved, onRejected){
        const that = this;
    
        // 向后传递成功的 value
        onResolved = typeof onResolved === 'function' ? onResolved : value => value
        // 指定默认的失败的回调 ( 实现错误/异常传投的关键点 ),向后传递失败的 reason
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
    
        /**
         * 返回一个新的 Promise 对象
         * 根据执行的结果,改变 return 的 promise 的状态
         */
        return new Promise((resolve, reject)=>{
            // 调用指定的函数处理
            function handle(callback){
                /**
                 * 分三种情况:
                 * 1. 如果回调函数返回的是 Promise,return 的 Promise 结果就是这个 Promise 的结果
                 * 2. 如果回调函数返回的不是 Promise,return 的 Promise 就会成功,value 就是返回的值
                 * 3. 如果抛出异常,return 的Promise就会失败,reason 就是 error
                 */
                try{
                    // 到回调函数的结果
                    const result = callback(that.data);
                    // 判断 result 的类型 
                    if(result instanceof Promise){
                        // 1. 如果回调函数返回的是 Promise,return 的 Promise 结果就是这个 Promise 的结果
                        // 注意:想要拿到 Promise 的结果只能 .then()
                        // 当 result 成功是,让 return 的 Promise 也成功 (resolve)
                        // 当 result 失败是,让 return 的 Promise 也失败 (reject)
    
                        // 普通写法
                        // result.then(
                        //     value => resolve(value), 
                        //     reject => reject(reject)
                        // )
    
                        // 简洁写法
                        result.then(resolve, reject);
                    }else{
                        // 2. 如果回调函数返回的不是 Promise,return 的 Promise 就会成功,value 就是返回的值
                        resolve(result);
                    }
                }catch(error){
                    // 3. 如果抛出异常,return 的Promise就会失败,reason 就是 error
                    reject(error);
                }
            }
    
            // 处理不同状态的 status
            if(that.status === PENDING ){
                // 如果status 为 pending,则保存回调函数
                that.callbacks.push({
                    onResolved(){  handle(onResolved) }, 
                    onRejected(){  handle(onRejected) }
                })
            }else if(that.status === RESOLVED){
                // 如果status 为 resolved,则异步执行 onResolve 并改变 return 的 promise 状态
                setTimeout(()=>{
                    handle(onResolved)
                })
            }else{
                // 如果status 为 rejected,则异步执行 onRejected 并改变 return 的 promise 状态
                setTimeout(()=>{
                    handle(onRejected)
                })
            }
        });  
    }
    
    /**
     * @func Promise 原型对象中的 catch()
     * @param onRejected 失败的回调函数
     * @returns 返回一个新的 Promise 对象
     */ 
    Promise.prototype.catch = function (onRejected) {
        return this.then(undefined, onRejected)
    }
    

    # 测试demo

    情景一:
    new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(1); 
            // reject(2)
        },100)
    }).then(
        value => {
            console.log('onResolved()1', value)
        },
        reason =>{
            console.log('onRejected()1', reason)
        }
    ).then(
        value => {
            console.log('onResolved()2', value)
        },
        reason =>{
            console.log('onRejected()2', reason)
        }
    );
    
    输出结果为:
    onResolved()1 1
    onResolved()2 undefined
    
    情景二:
    new Promise((resolve,reject)=>{
        setTimeout(()=>{
            // resolve(1); 
            reject(2)
        },100)
    }).then(
        value => {
            console.log('onResolved()1', value)
        },
        reason =>{
            console.log('onRejected()1', reason)
        }
    ).then(
        value => {
            console.log('onResolved()2', value)
        },
        reason =>{
            console.log('onRejected()2', reason)
        }
    );
    输出结果为:
    onRejected()1 2
    onResolved()2 undefined
    
    情景三:
    new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(1); 
            // reject(2)
        },100)
    }).then(
        value => {
            console.log('onResolved()1', value)
            throw 2
        },
        reason =>{
            console.log('onRejected()1', reason)
        }
    ).then(
        value => {
            console.log('onResolved()2', value)
        },
        reason =>{
            console.log('onRejected()2', reason)
            throw 3
        }
    ).catch(error => {
        console.log('onRejected()3', error)
    })
    输出结果为
    onResolved()1 1
    onRejected()2 2
    onRejected()3 3
    

    哇哦,又简单实现了一小步,我们不骄傲,继续努力~~

    下一篇:Promise .resolve() / reject() 的实现

    相关文章

      网友评论

          本文标题:手撕Promise真面目(手写 promise 代码没有那么难)

          本文链接:https://www.haomeiwen.com/subject/smjmvktx.html