手写CancelPromise

37 阅读1分钟
// 问题三:
// 实现一个可取消的 Promise,效果如下:
const res = new CancellablePromise((resolve) => {
  setTimeout(() => {
    // do something
    resolve();
  }, 1000);
}).then(() => {
  console.log('done');
}).stop(); // no 'done' in console

解决方案1 借助于Promise

class CancelPromise{
  constructor(func){
    this.cancel =false
      const newFuc = (resolve)=>{
        if(!this.cancel){
          func(resolve)
        }
      }
    this.promise = new Promise(newFuc)
  }
  then(thenFunc){
    this.promise.then((res)=>{
        if(!this.cancel){
          thenFunc(res)
        }
      })
    return this
  }
  stop(){
    this.cancel = true
  }
}
const ss = new CancelPromise((resolve)=>{
  setTimeout(()=>{
    resolve('okk')
  },1000)
})
.then(res=>{
  console.log('res', res)
})
.stop()

解决方案2 纯手写CancelPromise

class CancelPromise{
  #_STATUS_PENDING = 'pending'
  #_STATUS_RESOLVE = 'success'
  constructor(resolveHandler){
    this.status = this.#_STATUS_PENDING
    this.okValue = undefined
    this.errValue = undefined
    this.localThen = undefined
    this.cancel=false
    resolveHandler(this.#resolve)
  }
  #resolve = (res)=>{
    // console.log('#resolve', res)
    this.status = this.#_STATUS_RESOLVE
    this.okValue=res
    if(!this.cancel){
      this.localThen(res)
    }
  }

  then(localThen){
    this.localThen = localThen
    return this
  }

  stop(){
    this.cancel=true
  }
}

const cp = new CancelPromise((resolve)=>{
  setTimeout(()=>{
    resolve('okk')
  },3000)
})
.then(res=>{
  console.log('---then---', res)
})
.stop()