promise待完善

250 阅读1分钟
// // promise的使用
// new Promise((resolve, reject) => {
//   // resolve(1);
//   reject(2);
// }).then(
//   // value => {
//   //   console.log("value", value)
//   // },
//   // reason => {
//   //   console.log("reson", reason)
//   // }
// ).then(
//   value => {
//     console.log(">>>>>fufill", value)
//   },
//   reson => {
//     console.log(">>>>>reject", reson)
//   }
// )

class myPromise {
  constructor(executor) {
    if(typeof executor !== "function") {
      throw Error("NNNNN")
    }
    this.initValue()
    this.resolve = this.resolve.bind(this);
    this.reject = this.reject.bind(this);
    executor(this.resolve, this.reject)
  }

  initValue() {
    this.value = null;
    this.reason = null;
    this.state = "pending";
    this.onFullfilledCallbacks = [];
    this.onRejectCallbacks = [];
  }

  resolve(value) {
    // 状态改变,执行成功的回调函数
    if(this.state === "pending") {    
      this.state = "fullfiled"
      this.value = value
      this.onFullfilledCallbacks.forEach(fn => fn(this.value))
    }
  }

  reject(reason) {
    // 状态改变,执行失败的回调函数
    if(this.state === "pending") {    
      this.state = "reject"
      this.reason = reason
      this.onRejectCallbacks.forEach(fn => fn(this.value))
    }
  }

  then(onFullfiled, onReject) {
    // 实现链式调用,并返回后面then的值,必须通过新的实例
    if(typeof onFullfiled !== "function") {
      onFullfiled = function(value) {
        return value
      }
    }

    if(typeof onReject !== "function") {
      onReject = function(reason) {
        throw reason
      }
    }

    let promise2 = new myPromise((resolve, reject) => {
      if(this.state === "fullfiled") {
        setTimeout(() => {
          onFullfiled(this.value)
        })
      }
  
      if(this.state === "reject") {
        setTimeout(() => {
          onReject(this.value)
        })
      }
  
      if(this.state === "pending") {
        this.onFullfilledCallbacks.push(value => {
          setTimeout(() => {
            onFullfiled(value)
          })
        })
  
        this.onFullfilledCallbacks.push(reason => {
          setTimeout(() => {
            onFullfiled(reason)
          })
        })
      }
    })

    return promise2
  }

}

console.log('a')
new myPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('b')
  })
})
  // .then()
  .then(value => {
    console.log("_______", value)
  }, reason => {
  }).then(value => {
    console.log("++++++++", value)
  })
console.log('c')