Skip to content

Instantly share code, notes, and snippets.

@andyedinborough
Last active March 31, 2016 17:17
Show Gist options
  • Select an option

  • Save andyedinborough/61d4982a355421d2585b to your computer and use it in GitHub Desktop.

Select an option

Save andyedinborough/61d4982a355421d2585b to your computer and use it in GitHub Desktop.
class CancellablePromise {
constructor(executorOrPromise) {
let promise = executorOrPromise;
if (!promise.then) promise = new Promise(executorOrPromise);
this.cancelled = false;
this._resolved = false;
this._caught = false;
this._thens = [];
this._catches = [];
this._queue = this._thens;
this._result = null;
this._process = result => {
this._resolved = true;
const then = this._queue.shift();
if (then) {
try {
this._result = then(result);
} catch (x) {
_catch(x);
return;
}
if (this._result && this._result.then) {
this._result = new CancellablePromise(this._result)
.then(this._process)
.catch(this._process);
} else this._process(this._result);
}
};
const _then = result => this._process(result);
const _catch = result => {
this._caught = true;
this._queue = this._catches;
this._process(result);
};
promise
.then(_then)
.catch(_catch);
}
cancel() {
this.cancelled = true;
this._queue = this._catches;
this._resolved = true;
this._caught = true;
this._process({ cancelled: true });
}
then(func) {
this._thens.push(func);
if (this._resolved && !this._caught) {
this._process(this._result);
}
return this;
}
catch(func) {
this._catches.push(func);
if (this._resolved && this._caught) {
this._process(this._result);
}
return this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment