class ResponsePromise extends Promise {
  constructor(executor) {

    const progress = (event) => {
      this.progressCBQueue.forEach((cb)=> {
        cb(event);
      })
    };
    const onCancel =  (cb) => {
      //using nextTick because we cant use "this" before super()
      setTimeout(()=> {
        this.cancelCb = cb;
      })
    }

    const oExecutor = (resolve, reject) => {
      executor(resolve, progress,  reject, onCancel);
    }

    super(oExecutor);
    this.progressCBQueue = [];
    //this.cancelCb = null;
  }
  onProgress(cb) {
    this.progressCBQueue.push(cb);
  }
  cancel() {
    if (this.cancelCb) {
      this.cancelCb();
    } else {
      console.warn('onCancel not provided');
    }
  }
}
let p = new ResponsePromise((resolve, progress, reject, onCancel)=> {
  onCancel(()=> {
    console.log('OnCancel');
    //logic to cancel things
  })
  setTimeout(progress, 100)
  setTimeout(progress, 200)
  setTimeout(progress, 300)
  setTimeout(resolve, 500);

});

setTimeout(()=> {
  p.cancel();
}, 250)

p.then((data)=> {
  console.log('then called');
})

p.onProgress(()=> {
  console.log('onProgress callback')
})
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.