JS学习笔记—手写一个简易的Promise

<script>
  const PENDING = 'pending';
  const RESOLVED = 'resolved';
  const REJECTED = 'rejected';

  function MyPromise(fn){
    const that = this;
    that.state = PENDING;                //默认状态是pending
    that.value = null;                  //用来保存resolve或者reject中传入的值
    that.resolvedCallbacks = [];         //用于保存then中的回调,用于改变promise状态
    that.rejectedCallbacks = [];

    function resolve(value){
      if (value instanceof MyPromise){
        return value.then(resolve,reject);
      }
      setTimeout(() => {
        if (that.state === PENDING){
          that.value = RESOLVED;
          that.value = value;
          that.resolvedCallbacks.map(cb => cb(that.value));
        }
      },0)
    }
    function reject(value){
      setTimeout(() => {
        if (that.state === PENDING){
          that.value = REJECTED;
          that.value = value;
          that.rejectedCallbacks.map(cb => cb(that.value));
        }
      },0)
    }

    try {
      fn(resolve, reject)
    } catch (e) {
      reject(e)
    }
  }

  MyPromise.prototype.then = function(onFulfilled,onRejected){
    const that = this;
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
    onRejected = typeof onRejected === 'function' ? onRejected : r => { throw r}

    if (that.state === PENDING){
      return (promise2 = new MyPromise((resolve,reject) => {
        that.resolvedCallbacks.push(() => {
          try{
            const x = onFulfilled(that.value);
            resolutionProcedure(promise2,x,resolve,reject)
          }catch (r){
            reject(r)
          }
        })
        that.rejectedCallbacks.push(() => {
          try {
            const x = onRejected(that.value);
            resolutionProcedure(promise2,x,resolve,reject)
          }catch(r){
            reject(r)
          }
        })
      }))
    }
    if (that.state === RESOLVED){
      return (promise2 = new MyPromise((resolve,reject) => {
        setTimeout(() => {
          try{
            const x = onFulfilled(that.value);
            resolutionProcedure(promise2, x, resolve, reject)
          }catch(r){
            reject(r)
          }
        })
      }))
    }
    if (that.state === REJECTED){
      return (promise2 = new MyPromise((resolve,reject) => {
        setTimeout(() => {
          try{
            const x = onRejected(that.value);
            resolutionProcedure(promise2, x, resolve, reject)
          }catch(r){
            reject(r)
          }
        })
      }))
    }

    function resolutionProcedure (promise2, x, resolve, reject) {
      //规定了 x 不能与 promise2 相等,这样会发生循环引用的问题
      if (promise2 === x){
        return reject(new TypeError('Error'));
      }
      //判断 x 的类型
      if (x instanceof MyPromise){
        x.then(function(value){
          resolutionProcedure(promise2, value, resolve, reject)
        },reject)
      }

      let called = false;           //用户判断是否已经掉用过函数
      //判断 x 是否为对象或者函数,如果都不是的话,将 x 传入 resolve 中
      if (x !== null && (typeof x === 'object' || typeof x === 'function')){
        try{
          //如果 x 是对象或者函数的话,先把 x.then 赋值给 then,然后判断 then 的类型,如果不是函数类型的话,就将 x 传入 resolve 中
          //如果 then 是函数类型的话,就将 x 作为函数的作用域 this 调用之,并且传递两个回调函数作为参数,第一个参数叫做 resolvePromise ,第二个参数叫做 rejectPromise,两个回调函数都需要判断是否已经执行过函数,然后进行相应的逻辑
          let then = x.then;
          if (typeof then === 'function'){
            then.call(
              x,
              y => {
                if (called) return;
                called = true;
                resolutionProcedure(promise2, y, resolve,reject)
              },
              e => {
                if (called) return;
                called = true;
                reject(e);
              }
            )
          }else{
            resolve(x);
          }
        } catch(e) {}
        if (called) return;
        called = true;
        reject(e);
      }else {
        resolve(x);
      }
    }
  }

  new MyPromise((resolve, reject) => {
    setTimeout(() => {
      resolve(1)
    }, 0)
  }).then(value => {
    console.log(value)
  })
</script>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值