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

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

作者: 酷酷的凯先生 | 来源:发表于2020-11-02 15:21 被阅读0次

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

    # 第二步:Promise 构造函数的实现

    const PENDING = 'pending';
    const RESOLVED = 'resolved';
    const REJECTED = 'rejected';
    
    /**
     * @func Promise 函数模块
     * @param excutor 执行器函数(同步执行)
     */
    function Promise(excutor){
        const that =  this;
        // 1. 给 Promise 对象执定一个 status 属性,初始值为 pending
        that.status = PENDING;
        // 2. 给 Promise 对象指定一个 data 属性, 用于存储结果数据
        that.data = undefined;
        // 3. 所有的回调函数,每个元素的结构 { onResolved(){}, onRejected(){} }
        that.callbacks = [];
    
        // 定义一个 成功 的回调
        function resolve(value) {
            // 如果当前状态不是 pending,直接结束
            if(that.status !== PENDING ) return;
            
            // 1. 将状态改为 resolved
            that.status = RESOLVED;
            // 2. 保存数据
            that.data = value;
            // 如果有待执行的回调函数,立即一步执行
            if(that.callbacks.length > 0){
                // 放入异步队列中执行所有成功的回调(这里先这么模拟,后期再一步一步优化)
                setTimeout(()=>{
                    that.callbacks.forEach(callbacksObj => {
                        callbacksObj.onResoled(value);
                    });
                })
            }
        }
    
        // 定义一个 失败 的回调
        function reject(reason) {
                // 如果当前状态不是 pending,直接结束
            if(that.status !== PENDING ) return;
    
            // 1. 将状态改为 rejected
            that.status = REJECTED;
            // 2. 保存数据
            that.data = reason;
            // 如果有待执行的回调函数,立即一步执行
            if(that.callbacks.length > 0){
                // 放入异步队列中执行所有成功的回调(这里先这么模拟,后期再一步一步优化)
                setTimeout(()=>{
                    that.callbacks.forEach(callbacksObj => {
                        callbacksObj.onRejected(reason);
                    });
                })
            }
        }
    
        // 立即同步执行 excutor
        try{
            excutor(resolve, reject)
        }catch(error){
            // 如果执行抛出异常,Promise 对象状态变为 rejected
            reject(error)
        }
    }
    
    /**
     * @func Promise 原型对象中的 then()
     * @param onResoled 成功的回调函数
     * @param onRejected 失败的回调函数
     * @returns  返回一个新的 Promise 对象
     */
    Promise.prototype.then = function (onResoled, onRejected) {
        const that = this;
        // 假设状态还是 pending, 将回调函数保存起来(先这模拟,后期再一步一步优化)
        that.callbacks.push({ onResoled, onRejected })
    }
    

    # 测试 demo

    测试一下咱们写的代码,看看效果如何:

    onst p = new Promise((resolve,reject)=>{
      setTimeout(()=>{
        resolve(1); 
        // reject(2)
      },100)
    });
    
    p.then(
      value => {
         console.log('onResolved()1', value)
      },
      reason =>{
        console.log('onRejected()1', reason)
      }
    );
            
    p.then(
      value => {
        console.log('onResolved()2', value)
      },
      reason =>{
        console.log('onRejected()2', reason)
      }
    );
    
    // 输出结果为
    onResolved()1 1
    onResolved()2 1
    

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

    下一篇:Promise .then() / catch() 的实现

    相关文章

      网友评论

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

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