开发者社区> 问答> 正文

手写一个 Promise

手写一个 Promise

展开
收起
请回答1024 2020-04-07 20:57:40 760 0
1 条回答
写回答
取消 提交回答
  • const PENDING = "pending"; const RESOLVED = "resolved"; const REJECTED = "rejected";

    function MyPromise(fn) { // 保存初始化状态 var self = this;

    // 初始化状态 this.state = PENDING;

    // 用于保存 resolve 或者 rejected 传入的值 this.value = null;

    // 用于保存 resolve 的回调函数 this.resolvedCallbacks = [];

    // 用于保存 reject 的回调函数 this.rejectedCallbacks = [];

    // 状态转变为 resolved 方法 function resolve(value) { // 判断传入元素是否为 Promise 值,如果是,则状态改变必须等待前一个状态改变后再进行改变 if (value instanceof MyPromise) { return value.then(resolve, reject); }

    // 保证代码的执行顺序为本轮事件循环的末尾
    setTimeout(() => {
      // 只有状态为 pending 时才能转变,
      if (self.state === PENDING) {
        // 修改状态
        self.state = RESOLVED;
    
        // 设置传入的值
        self.value = value;
    
        // 执行回调函数
        self.resolvedCallbacks.forEach(callback => {
          callback(value);
        });
      }
    }, 0);
    

    }

    // 状态转变为 rejected 方法 function reject(value) { // 保证代码的执行顺序为本轮事件循环的末尾 setTimeout(() => { // 只有状态为 pending 时才能转变 if (self.state === PENDING) { // 修改状态 self.state = REJECTED;

        // 设置传入的值
        self.value = value;
    
        // 执行回调函数
        self.rejectedCallbacks.forEach(callback => {
          callback(value);
        });
      }
    }, 0);
    

    }

    // 将两个方法传入函数执行 try { fn(resolve, reject); } catch (e) { // 遇到错误时,捕获错误,执行 reject 函数 reject(e); } }

    MyPromise.prototype.then = function(onResolved, onRejected) { // 首先判断两个参数是否为函数类型,因为这两个参数是可选参数 onResolved = typeof onResolved === "function" ? onResolved : function(value) { return value; };

    onRejected = typeof onRejected === "function" ? onRejected : function(error) { throw error; };

    // 如果是等待状态,则将函数加入对应列表中 if (this.state === PENDING) { this.resolvedCallbacks.push(onResolved); this.rejectedCallbacks.push(onRejected); }

    // 如果状态已经凝固,则直接执行对应状态的函数

    if (this.state === RESOLVED) { onResolved(this.value); }

    if (this.state === REJECTED) { onRejected(this.value); } };

    2020-04-07 20:57:46
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载