面试常考点:手写一个简易版的Promise

要实现一个promise首先我们要知道以下几点:

1、对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:

  • pending: 初始状态,不是成功或失败状态。
  • fulfilled: 意味着操作成功完成。
  • rejected: 意味着操作失败。

只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态

2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果

以上具体可参考菜鸟教程Promise

话不多说先贴上代码:如下(先不考虑调用静态的resolvereject的话,如Promise.resolvePromise.reject

      class MyPromise {
        constructor(init) {
          this.status = "pending"; //promise的状态有:pending、fulfilled、rejected
          this.resoleList = []; //定义一个接收resolve的数组
          this.rejectList = []; //定义一个接收reject的数组
          this.value = ""; //接收值
          //提前捕获异常
          try {
            init(this._resolve.bind(this), this._reject.bind(this));
          } catch (error) {
            this._reject.call(this, error);
          }
        }

        then(cb) {
          cb && this.resoleList.push(cb); //cb有函数的话,先推到resoleList数组里面
          if (this.status === "fulfilled") {
            this.resoleList.forEach((v) => {
              v(this.value);
            });
          }
          return this; //为了可以链式调用,所有要返回它自己
        }
        catch(cb) {
          cb && this.rejectList.push(cb); //cb有函数的话,先推到rejectList数组里面
          if (this.status === "rejected") {
            this.rejectList.forEach((v) => {
              v(this.value);
            });
          }
          return this; //为了可以链式调用,所有要返回它自己
        }

        _resolve(value) {
          if (this.status === "pending") {
            this.status = "fulfilled";
            this.value = value;
            this.then.call(this);
          }
        }
        _reject(value) {
          if (this.status === "pending") {
            this.status = "rejected";
            this.value = value;
            this.catch.call(this);
          }
        }
      }

模拟正常调用一下 

new MyPromise((res, rej) => {
   res(12344);
}).then((res) => {
   console.log("ok:" + res);
})

 模拟网络延迟返回

new MyPromise((res, rej) => {
    setTimeout(() => {
       res(12344);
    }, 3000);
}).then((res) => {
   console.log("ok:" + res);
});

测试捕获异常

new MyPromise((res, rej) => {
    res(sss);//传入一个没有定义的sss进去
}).then((res) => {
   console.log("ok:" + res);
}).catch((error) => {
   console.log("error", error);
});

捕获正常 

 

 

 模拟状态值改变后不再变化

new MyPromise((res, rej) => {
    setTimeout(() => {
      rej("异常");//先执行状态为rejected
      res(12344);//再测试改成fulfilled
    }, 3000);
}).then((res) => {
    console.log("网络ok:" + res);
}).catch((error) => {
    console.log("error", error);
});

ok,只打印catch的内容,没有执行then内容,说明正常 

 

 测试连续then链式调用

new MyPromise((res, rej) => {
    setTimeout(() => {
      res(12344);
    }, 3000);
}).then((res) => {
   console.log("网络ok:" + res);
}).then((data) => {
   console.log("哈哈", data);
}).catch((error) => {
   console.log("error", error);
});

也是能正常执行 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值