手写简单promise

第一步,主要实现new promise类的时候,执行resolve和rejected的状态改变
调用这个类
  let p = new myPromise((resolve, reject) => {
     
    resolve('成功啦')
    reject('失败啦')
  })
  p.resolve()
封装的类
class myPromise {
     
  // 下面这些是定义到对象里使用的变量
  static pending = 'pending'
  static full = 'full'
  static reje = 'reje'
  static that = this
  constructor(executor) {
        // 这里面的this是指当前对象
    console.log(executor);
    this.status = this.pending
    this.value = null
    executor(this.resolve.bind(this), this.reject.bind(this))  
    // 这里需要绑定bind(this),因为executor是传进来的函数,然后把这两个方法传进去调用
    // 也就是产生了新的作用域,然后因为类里面是严格模式,那么这里面的this就是undefind
    // 所以必须里面的方法调用的时候必须是指向当前this的,也就是当前类,才拿得到当前类的数据和this
    // this.resolve()  // 像这样正常的调用的话,里面的this指的是当前的类的
  }
  // 在construct外面是受严格模式控制的
  resolve(value) {
     
    console.log(this);
    this.status = myPromise.full
    this.value = value

  }
  reject(value) {
     
    this.status = myPromise.reje
    this.value = value
  }
}

第二步 构造then方法,然后构建异常处理,和异步处理

调用的时候
  let p = new myPromise((resolve, reject) => {
     
    // resolve('成功啦')
    reject('失败啦')
  }).then(res => {
     
    console.log(aaa);
  }, err => {
     
    console.log(err);
  })
  console.log('我是傻逼');

具体类

class myPromise {
     
  // 下面这些是定义到对象里使用的变量
  static pending = 'pending'
  static full = 'full'
  static reje = 'reje'
  static that = this
  constructor(executor) {
      // 这里面的this是指当前对象
    this.status = myPromise.pending
    this.value = null
    // 假如传递进来参数有问题,就会报错,那么为了解决这种问题
    try {
     
      executor(this.resolve.bind(this), this.reject.bind(this)) // 这里需要绑定bind(this),因为executor是传进来的函数,然后把这两个方法传进去调用
      // 也就是产生了新的作用域,然后因为类里面是严格模式,那么这里面的this就是undefind
      // 所以必须里面的方法调用的时候必须是指向当前this的,也就是当前类,才拿得到当前类的数据和this
    } catch (error) {
     
      this.reject()
    }


    // this.resolve()  // 像这样正常的调用的话,里面的this指的是当前的类的
  }
  // 在construct外面是受严格模式控制的
  resolve(value) {
     
    if (this.status === myPromise.pending) {
     
      this.status = myPromise.full
      this.value = value
    }
  }
  reject(value) {
     
    if (this.status === myPromise.pending) {
     
      this.status = myPromise.reje
      this.value = value
    }
  }
  then(onFulfilled, onRejected) {
     
    if (typeof onFulfilled !== "function") {
     
      onFulfilled = () => {
     }
    }
    if (this.status === myPromise.full) {
     
      // 放到定时器里面是因为promise的回调是异步的,异步的就是要放到任务队列里面的,所以使用定时器
      setTimeout(() => {
     
        // try catch是为了防止传过来的onFulfilled有错误,有错误的话就调用输出错误的方法
        try {
     
          onFulfilled(this.value)
        } catch (error) {
     
          onRejected(error)
        }
      })
    }
    if (typeof onRejected !== "function") {
     
      onRejected = () => {
     }
    }
    if (this.status === myPromise.reje) {
     
      // 放到定时器里面是因为promise的回调是异步的,异步的就是要放到任务队列里面的,所以使用定时器
      setTimeout(() => {
     
        // try catch是为了防止传过来的onFulfilled有错误,有错误的话就调用输出错误的方法
        try {
     
          onRejected(this.value)
        } catch (error) {
     
          onRejected(error)
        }
      })
    }
  }
}

第三步

处理如果resolve调用比then调用慢时候情况,比如加了定时器
调用
  let p = new myPromise((resolve, reject) => {
     
    setTimeout(() => {
     
      resolve('成功啦')
    })
    // reject('失败啦')
  }).then(res => {
     
    console.log(res);
  }, err => {
     
    console.log(err);
  })

class myPromise {
     
  // 下面这些是定义到对象里使用的变量
  static pending = 'pending'
  static full = 'full'
  static reje = 'reje'
  static that = this
  constructor(executor) {
      // 这里面的this是指当前对象
    this.status = myPromise.pending
    this.value = null
    this.callbasek = []
    // 假如传递进来参数有问题,就会报错,那么为了解决这种问题
    try {
     
      executor(this.resolve.bind(this), this.reject.bind(this)) // 这里需要绑定bind(this),因为executor是传进来的函数,然后把这两个方法传进去调用
      // 也就是产生了新的作用域,然后因为类里面是严格模式,那么这里面的this就是undefind
      // 所以必须里面的方法调用的时候必须是指向当前this的,也就是当前类,才拿得到当前类的数据和this
    } catch (error) {
     
      this.reject()
    }


    // this.resolve()  // 像这样正常的调用的话,里面的this指的是当前的类的
  }
  // 在construct外面是受严格模式控制的
  resolve(value) {
     
    if (this.status === myPromise.pending) {
     
      this.status = myPromise.full
      this.value = value
      // 位置2,正常执行的时候, this.callbasek是空数组所以不受影响,如果调用的时候resolve外面使用了类似定时器的东西
      // 就会影响到resolve的调用速度慢于then,然后再then里面保存方法到this.callbasek,现在调用
      this.callbasek.map(item => {
     

        item.onFulfilled(value)
      })
    }
  }
  reject(value) {
     
    if (this.status === myPromise.pending) {
     
      this.status = myPromise.reje
      this.value = value
      this.callbasek.map(item => {
     
        item.onRejected(value)
      })
    }
  }
  then(onFulfilled, onRejected) {
     
    if (typeof onFulfilled !== "function") {
     
      onFulfilled = () => {
     }
    }
    if (this.status === myPromise.full) {
     
      // 放到定时器里面是因为promise的回调是异步的,异步的就是要放到任务队列里面的,所以使用定时器
      setTimeout(() => {
     
        // try catch是为了防止传过来的onFulfilled有错误,有错误的话就调用输出错误的方法
        try {
     
          onFulfilled(this.value)
        } catch (error) {
     
          onRejected(error)
        }
      })
    }
    if (typeof onRejected !== "function") {
     
      onRejected = () => {
     }
    }
    if (this.status === myPromise.reje) {
     
      // 放到定时器里面是因为promise的回调是异步的,异步的就是要放到任务队列里面的,所以使用定时器
      setTimeout(() => {
     
        // try catch是为了防止传过来的onFulfilled有错误,有错误的话就调用输出错误的方法
        try {
     
          onRejected(this.value)
        } catch (error) {
     
          onRejected(error)
        }
      })
    }

    //  位置1,下面是把then里面的方法存起来,因为此时resolve或者reject还没执行,需要等到他们执行的时候再拿出来
    if (this.status === myPromise.pending) {
     
      this.callbasek.push({
     
        onFulfilled: value => {
      // 这个value就是在调用这里的这个函数的时候传进来的值,因为上面调用是传进来这个值的
          // 下面使用错误判断
          try {
     
            onFulfilled(value)
            
          } catch (error) {
     
            onRejected(error)
          }
        },
        onRejected: value => {
     
          try {
     
            onRejected(value)
          } catch (error) {
     
            onRejected(error)
          }
        }
      })
    }
  }
}

第四步,处理链式then执行,还有异常处理

调用
  let p = new myPromise((resolve, reject) => {
     
    resolve('成功啦')
    // reject('失败啦')
  }).then(res => {
     
    console.log(aaa);
    return '你成功啦'
  }, err => {
     
    console.log(err);
    return '你也成功啦'
  }).then(res => {
     
    console.log('第二个then' + res);
  }, err => {
     
    console.log('错误' + err);
  })

class myPromise {
     
  // 下面这些是定义到对象里使用的变量
  static pending = 'pending'
  static full = 'full'
  static reje = 'reje'
  static that = this
  constructor(executor) {
      // 这里面的this是指当前对象
    console.log(1);
    this.status = myPromise.pending
    this.value = null
    this.callbasek = []
    // 假如传递进来参数有问题,就会报错,那么为了解决这种问题
    try {
     
      executor(this.resolve.bind(this), this.reject.bind(this)) // 这里需要绑定bind(this),因为executor是传进来的函数,然后把这两个方法传进去调用
      // 也就是产生了新的作用域,然后因为类里面是严格模式,那么这里面的this就是undefind
      // 所以必须里面的方法调用的时候必须是指向当前this的,也就是当前类,才拿得到当前类的数据和this
    } catch (error) {
     
      this.reject()
    }
    // this.resolve()  // 像这样正常的调用的话,里面的this指的是当前的类的
  }
  // 在construct外面是受严格模式控制的
  resolve(value) {
     
    console.log(value);
    if (this.status === myPromise.pending) {
     
      this.status = myPromise.full
      this.value = value
      // 正常执行的时候, this.callbasek是空数组所以不受影响,如果调用的时候resolve外面使用了类似定时器的东西
      // 就会影响到resolve的调用速度慢于then,然后再then里面保存方法到this.callbasek,现在调用
      console.log(this.callbasek);
      this.callbasek.map(item => {
     
        item.onFulfilled(value)
      })
    }
  }
  reject(value) {
     
    if (this.status === myPromise.pending) {
     
      this.status = myPromise.reje
      this.value = value
      console.log(this.value);
      this.callbasek.map(item => {
     
        item.onRejected(value)
      })
    }
  }
  // 在执行到定时器的时候,第二then也会马上执行
  then(onFulfilled, onRejected) {
     
    console.log(onFulfilled);
    console.log(onRejected);
    if (typeof onFulfilled !== "function") {
     
      onFulfilled = () => {
     }
    }
    if (typeof onRejected !== "function") {
     
      onRejected = () => {
     }
    }
    // 要下一个then执行成功就需要执行完then的时候把当前类new一编再返回出去
    // 因为再构造函数里面有传进来一个函数,然后把resolve和reject传进去,因为这函数里面就是执行这两个方法的
    // 那为什么这个代码里面要把then的实现内容包住呢,因为需要在上一个then那里拿到resolve,才会去执行下一个then
    /* 
    链式then执行过程:
    一、在new myPromise的时候传进来了一个函数,函数里面的是resolve或者reject的执行,把这个函数传进到构造函数里面,会在构造函数里面执行
      并且会传当前的类的resolve或者reject进去,这样就执行了当前的resolve或者reject。这样就可以设置当前的状态和传到resolve或者reject里面的值
    二、然后执行第一个then函数,在调用的时候,会传进来两个函数,然后通过new myPromise传来的函数而设置的状态来执行相应函数,并且
      在then里面传的两个函数return 回来一个值,并且把这个值通过resolve或者reject保存到类中的status和value中
    三、由于上面判断状态执行函数是放在定时器里面的,所以当then函数一执行到定时器那里,这个then就执行完毕了
    四、然后就开始执行第二个then,第二个then会初始化所有状态和值,所以此时进来的是pending状态的,然后执行完毕后
      马上就执行定时器里面的回调方法,于是第一个then里面函数就执行了,然后拿到第一个里面的return值后
      执行resolve,由于进来是准备状态,所以已经把then里面传进来的函数进行保存了,然后现在就执行保存的函数就可以了,于是第二then传的函数就执行了
    五、为了能够让上一个then和下一个then的关系连在一起,为了把一个then的异常交给下一个
      then去处理,所以把then的内容包再然后的new myPromise 里面
    
    
    */
    return new myPromise((resolve, reject) => {
     
      console.log(resolve);
      console.log(reject);
      console.log(this.status);
      console.log(this.value);
      if (this.status === myPromise.full) {
     
        // 放到定时器里面是因为promise的回调是异步的,异步的就是要放到任务队列里面的,所以使用定时器
        setTimeout(() => {
     
          // try catch是为了防止传过来的onFulfilled有错误,有错误的话就调用输出错误的方法
          try {
     
            let res = onFulfilled(this.value)
            console.log(res);
            resolve(res) // 执行他是为了改变状态和当前的value
            console.log(this.status);
            console.log(this.value);
          } catch (error) {
     
            // 这里的异常处理,为什么不用onRejected(error),因为此时这个函数里面的东西最后是用来返回东西给下一个then的,异常了
            // 就应该不返回,所以应该使用类里的这处理错误的方法来处理
            // onRejected(error)
            console.log(error);
            console.log(reject);
            reject(error)
          }
        })
      }
      if (this.status === myPromise.reje) {
     
        // 放到定时器里面是因为promise的回调是异步的,异步的就是要放到任务队列里面的,所以使用定时器
        setTimeout(() => {
     
          // try catch是为了防止传过来的onFulfilled有错误,有错误的话就调用输出错误的方法
          try {
     
            let res = onRejected(this.value)
            resolve(res)
          } catch (error) {
     
            // onRejected(error)
            reject(error)
          }
        })
      }
      // 下面是把then里面的方法存起来,因为此时resolve或者reject还没执行,需要等到他们执行的时候再拿出来
      if (this.status === myPromise.pending) {
     
        console.log('我到啦');
        this.callbasek.push({
     
          onFulfilled: value => {
      // 这个value就是在调用这里的这个函数的时候传进来的值,因为上面调用是传进来这个值的
            // 下面使用错误判断
            try {
     
              console.log(value);
              let res = onFulfilled(value)

              resolve(res)
            } catch (error) {
     
              // onRejected(error)
              reject(error)
            }
          },
          onRejected: value => {
     
            try {
     
              let res = onRejected(value)
              resolve(res)
            } catch (error) {
     
              // onRejected(error)
              reject(error)
            }
          }
        })
      }
    })
  }
}

手写简单promise_第1张图片

  • promise的返回值是不能跟当前的类一样的

处理resolve方法和reject方法

 myPromise.resolve('大傻逼').then(res => {
     
    console.log(res);
  })
  myPromise.reject('大傻逼22').then(null, res => {
     
    console.log(res);
  })
class myPromise {
     
  // 下面这些是定义到对象里使用的变量
  static pending = 'pending'
  static full = 'full'
  static reje = 'reje'
  static that = this
  constructor(executor) {
      // 这里面的this是指当前对象
    console.log(1);
    this.status = myPromise.pending
    this.value = null
    this.callbasek = []
    // 假如传递进来参数有问题,就会报错,那么为了解决这种问题
    try {
     
      executor(this.resolve.bind(this), this.reject.bind(this)) // 这里需要绑定bind(this),因为executor是传进来的函数,然后把这两个方法传进去调用
      // 也就是产生了新的作用域,然后因为类里面是严格模式,那么这里面的this就是undefind
      // 所以必须里面的方法调用的时候必须是指向当前this的,也就是当前类,才拿得到当前类的数据和this
    } catch (error) {
     
      this.reject()
    }
    // this.resolve()  // 像这样正常的调用的话,里面的this指的是当前的类的
  }
  // 在construct外面是受严格模式控制的
  resolve(value) {
     
    console.log(value);
    if (this.status === myPromise.pending) {
     
      this.status = myPromise.full
      this.value = value
      // 正常执行的时候, this.callbasek是空数组所以不受影响,如果调用的时候resolve外面使用了类似定时器的东西
      // 就会影响到resolve的调用速度慢于then,然后再then里面保存方法到this.callbasek,现在调用
      console.log(this.callbasek);
      this.callbasek.map(item => {
     
        item.onFulfilled(value)
      })
    }
  }
  reject(value) {
     
    if (this.status === myPromise.pending) {
     
      this.status = myPromise.reje
      this.value = value
      console.log(this.value);
      this.callbasek.map(item => {
     
        item.onRejected(value)
      })
    }
  }
  // 在执行到定时器的时候,第二then也会马上执行
  then(onFulfilled, onRejected) {
     
    console.log(onFulfilled);
    console.log(onRejected);
    if (typeof onFulfilled !== "function") {
     
      // then的穿透
      // 这里是为了如果传进来的then没有传函数的话,就返回当前保存的上一个then或者new 当前类传进来值,
      // 当执行这个不传参数的then的时候,就会这里设置这个函数,然后根据状态执行相对应的方法
      // 这样就把上一个then的值传给你下一个then
      // 当走下一个then的时候,
      onFulfilled = () => this.value
    }
    if (typeof onRejected !== "function") {
     
      console.log(this.value);
      onRejected = () => this.value
    }
    // 要下一个then执行成功就需要执行完then的时候把当前类new一编再返回出去
    // 因为再构造函数里面有传进来一个函数,然后把resolve和reject传进去,因为这函数里面就是执行这两个方法的
    // 那为什么这个代码里面要把then的实现内容包住呢,因为需要在上一个then那里拿到resolve,才会去执行下一个then
    /* 
    链式then执行过程:
    一、在new myPromise的时候传进来了一个函数,函数里面的是resolve或者reject的执行,把这个函数传进到构造函数里面,会在构造函数里面执行
      并且会传当前的类的resolve或者reject进去,这样就执行了当前的resolve或者reject。这样就可以设置当前的状态和传到resolve或者reject里面的值
    二、然后执行第一个then函数,在调用的时候,会传进来两个函数,然后通过new myPromise传来的函数而设置的状态来执行相应函数,并且
      在then里面传的两个函数return 回来一个值,并且把这个值通过resolve或者reject保存到类中的status和value中
    三、由于上面判断状态执行函数是放在定时器里面的,所以当then函数一执行到定时器那里,这个then就执行完毕了
    四、然后就开始执行第二个then,第二个then会初始化所有状态和值,所以此时进来的是pending状态的,然后执行完毕后
      马上就执行定时器里面的回调方法,于是第一个then里面函数就执行了,然后拿到第一个里面的return值后
      执行resolve,由于进来是准备状态,所以已经把then里面传进来的函数进行保存了,然后现在就执行保存的函数就可以了,于是第二then传的函数就执行了
    五、为了能够让上一个then和下一个then的关系连在一起,为了把一个then的异常交给下一个
      then去处理,所以把then的内容包再然后的new myPromise 里面
    
    
    */
    // 把promise拿出来,用来判断是否和调用then时候的返回值是否一样,因为不可以一样
    let promise = new myPromise((resolve, reject) => {
     
      console.log(resolve);
      console.log(reject);
      console.log(this.status);
      console.log(this.value);
      if (this.status === myPromise.full) {
     
        // 放到定时器里面是因为promise的回调是异步的,异步的就是要放到任务队列里面的,所以使用定时器
        setTimeout(() => {
     
          // try catch是为了防止传过来的onFulfilled有错误,有错误的话就调用输出错误的方法
          try {
     
            let res = onFulfilled(this.value)
            console.log(res);
            console.log(promise);
            console.log(res = promise);
            if (promise === res) {
     
              throw new TypeError('返回值不可以是当前的promise')
            }
            // 判断返回回来是又new 的一个类还是直接的值
            if (res instanceof myPromise) {
     
              // 如果是的话,那么这个类已经是经过构造函数的执行的了,然后根据他调用的方法来判断当前的状态
              // 比如是调用resolve方法的就会来到这里,然后要拿到resolve里面传的值,就需要调用then方法
              // 给then传递下面这个方法,就又会执行当前这个大的判断状态的方法,这样又执行上面的onFulfilled方法,
              // 这个方法就是调用下面这里面的resolve方法,这样后面的then就能拿到这个value了
              res.then(resolve, reject)
            } else {
     
              console.log(res);
              resolve(res) // 执行他是为了改变状态和当前的value
              console.log(this.status);
              console.log(this.value);
            }
          } catch (error) {
     
            // 这里的异常处理,为什么不用onRejected(error),因为此时这个函数里面的东西最后是用来return返回东西给下一个then的,异常了
            // 就应该不返回,所以应该使用类里的这处理错误的方法来处理,并且,当第二个
            // onRejected(error)
            console.log('我有错误');
            console.log(error);
            console.log(reject);
            reject(error)
          }
        })
      }
      if (this.status === myPromise.reje) {
     
        // 放到定时器里面是因为promise的回调是异步的,异步的就是要放到任务队列里面的,所以使用定时器
        setTimeout(() => {
     
          // try catch是为了防止传过来的onFulfilled有错误,有错误的话就调用输出错误的方法
          try {
     
            let res = onRejected(this.value)
            console.log(res = promise);
            if (promise == res) {
     
              throw new TypeError('返回值不可以是当前的promise')
            }
            if (res instanceof myPromise) {
     
              res.then(resolve, reject)
            } else {
     
              resolve(res)
            }

          } catch (error) {
     
            // onRejected(error)
            reject(error)
          }
        })
      }
      // 下面是把then里面的方法存起来,因为此时resolve或者reject还没执行,需要等到他们执行的时候再拿出来
      if (this.status === myPromise.pending) {
     
        console.log('我到啦');
        this.callbasek.push({
     
          onFulfilled: value => {
      // 这个value就是在调用这里的这个函数的时候传进来的值,因为上面调用是传进来这个值的
            // 下面使用错误判断
            try {
     
              console.log(value);
              let res = onFulfilled(value)
              console.log(res = promise);
              if (promise == res) {
     
                throw new TypeError('返回值不可以是当前的promise')
              }
              if (res instanceof myPromise) {
     
                res.then(resolve, reject)
              } else {
     
                resolve(res)
              }
              console.log(res);

            } catch (error) {
     
              // onRejected(error)
              reject(error)
            }
          },
          onRejected: value => {
     
            try {
     
              let res = onRejected(value)
              console.log(res = promise);
              if (res instanceof myPromise) {
     
                res.then(resolve, reject)
              } else {
     
                resolve(res)
              }
            } catch (error) {
     
              // onRejected(error)
              reject(error)
            }
          }
        })
      }

    })
    return promise
  }
  // resolve方法和reject方法,并且判断是否纯进来的是promise
  static resolve(value) {
     
    return new myPromise((resolve, reject) => {
     
      if (value instanceof myPromise) {
     
        value.then(resolve, reject)
      } else {
     
        resolve(value)
      }

    })
  }
  static reject(value) {
     
    return new myPromise((resolve, reject) => {
     

      if (value instanceof myPromise) {
     
        value.then(resolve, reject)
      } else {
     
        reject(value)
      }
    })
  }
}

all方法和race方法实现

class myPromise {
     
  // 下面这些是定义到对象里使用的变量
  static pending = 'pending'
  static full = 'full'
  static reje = 'reje'
  static that = this
  constructor(executor) {
      // 这里面的this是指当前对象
    console.log(1);
    this.status = myPromise.pending
    this.value = null
    this.callbasek = []
    // 假如传递进来参数有问题,就会报错,那么为了解决这种问题
    try {
     
      executor(this.resolve.bind(this), this.reject.bind(this)) // 这里需要绑定bind(this),因为executor是传进来的函数,然后把这两个方法传进去调用
      // 也就是产生了新的作用域,然后因为类里面是严格模式,那么这里面的this就是undefind
      // 所以必须里面的方法调用的时候必须是指向当前this的,也就是当前类,才拿得到当前类的数据和this
    } catch (error) {
     
      this.reject()
    }
    // this.resolve()  // 像这样正常的调用的话,里面的this指的是当前的类的
  }
  // 在construct外面是受严格模式控制的
  resolve(value) {
     
    console.log(value);
    if (this.status === myPromise.pending) {
     
      this.status = myPromise.full
      this.value = value
      // 正常执行的时候, this.callbasek是空数组所以不受影响,如果调用的时候resolve外面使用了类似定时器的东西
      // 就会影响到resolve的调用速度慢于then,然后再then里面保存方法到this.callbasek,现在调用
      console.log(this.callbasek);
      this.callbasek.map(item => {
     
        item.onFulfilled(value)
      })
    }
  }
  reject(value) {
     
    if (this.status === myPromise.pending) {
     
      this.status = myPromise.reje
      this.value = value
      console.log(this.value);
      this.callbasek.map(item => {
     
        item.onRejected(value)
      })
    }
  }
  // 在执行到定时器的时候,第二then也会马上执行
  then(onFulfilled, onRejected) {
     
    console.log(onFulfilled);
    console.log(onRejected);
    if (typeof onFulfilled !== "function") {
     
      // then的穿透
      // 这里是为了如果传进来的then没有传函数的话,就返回当前保存的上一个then或者new 当前类传进来值,
      // 当执行这个不传参数的then的时候,就会这里设置这个函数,然后根据状态执行相对应的方法
      // 这样就把上一个then的值传给你下一个then
      // 当走下一个then的时候,
      onFulfilled = () => this.value
    }
    if (typeof onRejected !== "function") {
     
      console.log(this.value);
      onRejected = () => this.value
    }
    // 要下一个then执行成功就需要执行完then的时候把当前类new一编再返回出去
    // 因为再构造函数里面有传进来一个函数,然后把resolve和reject传进去,因为这函数里面就是执行这两个方法的
    // 那为什么这个代码里面要把then的实现内容包住呢,因为需要在上一个then那里拿到resolve,才会去执行下一个then
    /* 
    链式then执行过程:
    一、在new myPromise的时候传进来了一个函数,函数里面的是resolve或者reject的执行,把这个函数传进到构造函数里面,会在构造函数里面执行
      并且会传当前的类的resolve或者reject进去,这样就执行了当前的resolve或者reject。这样就可以设置当前的状态和传到resolve或者reject里面的值
    二、然后执行第一个then函数,在调用的时候,会传进来两个函数,然后通过new myPromise传来的函数而设置的状态来执行相应函数,并且
      在then里面传的两个函数return 回来一个值,并且把这个值通过resolve或者reject保存到类中的status和value中
    三、由于上面判断状态执行函数是放在定时器里面的,所以当then函数一执行到定时器那里,这个then就执行完毕了
    四、然后就开始执行第二个then,第二个then会初始化所有状态和值,所以此时进来的是pending状态的,然后执行完毕后
      马上就执行定时器里面的回调方法,于是第一个then里面函数就执行了,然后拿到第一个里面的return值后
      执行resolve,由于进来是准备状态,所以已经把then里面传进来的函数进行保存了,然后现在就执行保存的函数就可以了,于是第二then传的函数就执行了
    五、为了能够让上一个then和下一个then的关系连在一起,为了把一个then的异常交给下一个
      then去处理,所以把then的内容包再然后的new myPromise 里面
    
    
    */
    // 把promise拿出来,用来判断是否和调用then时候的返回值是否一样,因为不可以一样
    let promise = new myPromise((resolve, reject) => {
     
      console.log(resolve);
      console.log(reject);
      console.log(this.status);
      console.log(this.value);
      if (this.status === myPromise.full) {
     
        // 放到定时器里面是因为promise的回调是异步的,异步的就是要放到任务队列里面的,所以使用定时器
        setTimeout(() => {
     
          // try catch是为了防止传过来的onFulfilled有错误,有错误的话就调用输出错误的方法
          try {
     
            let res = onFulfilled(this.value)
            console.log(res);
            console.log(promise);
            console.log(res = promise);
            if (promise === res) {
     
              throw new TypeError('返回值不可以是当前的promise')
            }
            // 判断返回回来是又new 的一个类还是直接的值
            if (res instanceof myPromise) {
     
              // 如果是的话,那么这个类已经是经过构造函数的执行的了,然后根据他调用的方法来判断当前的状态
              // 比如是调用resolve方法的就会来到这里,然后要拿到resolve里面传的值,就需要调用then方法
              // 给then传递下面这个方法,就又会执行当前这个大的判断状态的方法,这样又执行上面的onFulfilled方法,
              // 这个方法就是调用下面这里面的resolve方法,这样后面的then就能拿到这个value了
              res.then(resolve, reject)
            } else {
     
              console.log(res);
              resolve(res) // 执行他是为了改变状态和当前的value
              console.log(this.status);
              console.log(this.value);
            }
          } catch (error) {
     
            // 这里的异常处理,为什么不用onRejected(error),因为此时这个函数里面的东西最后是用来return返回东西给下一个then的,异常了
            // 就应该不返回,所以应该使用类里的这处理错误的方法来处理,并且,当第二个
            // onRejected(error)
            console.log('我有错误');
            console.log(error);
            console.log(reject);
            reject(error)
          }
        })
      }
      if (this.status === myPromise.reje) {
     
        // 放到定时器里面是因为promise的回调是异步的,异步的就是要放到任务队列里面的,所以使用定时器
        setTimeout(() => {
     
          // try catch是为了防止传过来的onFulfilled有错误,有错误的话就调用输出错误的方法
          try {
     
            let res = onRejected(this.value)
            console.log(res = promise);
            if (promise == res) {
     
              throw new TypeError('返回值不可以是当前的promise')
            }
            if (res instanceof myPromise) {
     
              res.then(resolve, reject)
            } else {
     
              resolve(res)
            }

          } catch (error) {
     
            // onRejected(error)
            reject(error)
          }
        })
      }
      // 下面是把then里面的方法存起来,因为此时resolve或者reject还没执行,需要等到他们执行的时候再拿出来
      if (this.status === myPromise.pending) {
     
        console.log('我到啦');
        this.callbasek.push({
     
          onFulfilled: value => {
      // 这个value就是在调用这里的这个函数的时候传进来的值,因为上面调用是传进来这个值的
            // 下面使用错误判断
            try {
     
              console.log(value);
              let res = onFulfilled(value)
              console.log(res = promise);
              if (promise == res) {
     
                throw new TypeError('返回值不可以是当前的promise')
              }
              if (res instanceof myPromise) {
     
                res.then(resolve, reject)
              } else {
     
                resolve(res)
              }
              console.log(res);

            } catch (error) {
     
              // onRejected(error)
              reject(error)
            }
          },
          onRejected: value => {
     
            try {
     
              let res = onRejected(value)
              console.log(res = promise);
              if (res instanceof myPromise) {
     
                res.then(resolve, reject)
              } else {
     
                resolve(res)
              }
            } catch (error) {
     
              // onRejected(error)
              reject(error)
            }
          }
        })
      }

    })
    return promise
  }
  // resolve方法和reject方法,并且判断是否纯进来的是promise
  static resolve(value) {
     
    return new myPromise((resolve, reject) => {
     
      if (value instanceof myPromise) {
     
        value.then(resolve, reject)
      } else {
     
        resolve(value)
      }

    })
  }
  static reject(value) {
     
    return new myPromise((resolve, reject) => {
     

      if (value instanceof myPromise) {
     
        value.then(resolve, reject)
      } else {
     
        reject(value)
      }
    })
  }
  static all(promises) {
     
    return new myPromise((resolve, reject) => {
     
      let values = []
      promises.forEach(promise => {
     
        promise.then(value => {
     
            // 原理:如果每一个promise都是调用reslove,那么我们就传当前值返回出去
            values.push(value)
            if (values.length === promises.length) {
     
              resolve()
            }
          },
          err => {
     
            console.log(err);
          })
      })
    })
  }
  static race(promises) {
     
    // 原理就是谁先执行完马上就调用resovle返回回去,就可以实现race的调用快执行的作用
    return new myPromise((resolve, reject) => {
     
      promises.forEach(promise => {
     
        promise.then(value => {
     
          resolve(value)
        }, err => {
     
          reject(err)
        })
      })
    })
  }

}

你可能感兴趣的:(es6)