Cancellable Promise (you don't cancel Promises, you cancel what they are waiting on)

by Gregg Tavares

JavaScript

class CancellableTimeout {
  constructor(timeout) {
    this._promise = new Promise((resolve, reject) => {
      this._resolve = resolve;
      this._reject = reject;
    });
    this._requestId = setTimeout(() => {
      this._requestId = 0;
      this._resolve();
    }, timeout);
  }
  get promise() {
    return this._promise;
  }
  cancel() {
    if (this._requestId) {      
      clearTimeout(this._requestId); 
      this._requestId = 0;
      this._reject();
    }
  }
}

const ct1 = new CancellableTimeout(2000);
ct1.promise.then(() => {
  log('promise1 resolved');
})
.catch(() => {
  log('promise1 rejected because timeout was cancelled');
});

const ct2 = new CancellableTimeout(2000);
ct2.promise.then(() => {
  log('promise2 resolved');
})
.catch(() => {
  log('promise2 rejected because timeout was cancelled');
});

setTimeout(() => {
  ct2.cancel();
}, 1000);





function log(...args) {
  const elem = document.createElement('div');
  elem.textContent = [...args].join(' ');
  document.body.appendChild(elem);
}