美文网首页
手撕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