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.

Revisions

  1. andyedinborough revised this gist Mar 31, 2016. 1 changed file with 16 additions and 52 deletions.
    68 changes: 16 additions & 52 deletions CancellablePromise.js
    Original file line number Diff line number Diff line change
    @@ -1,67 +1,31 @@
    class CancellablePromise {
    constructor(executorOrPromise) {
    let promise = executorOrPromise;
    if (!promise.then) promise = new Promise(executorOrPromise);
    const noop = () => {};

    this.cancelled = false;
    this._resolved = false;
    this._caught = false;
    this._thens = [];
    this._catches = [];
    this._queue = this._thens;
    this._result = null;
    export default class CancellablePromise {
    constructor(executorOrPromise){
    this._promise = new Promise((resolve, reject) => {
    let promise = executorOrPromise;
    if(!promise.then) promise = new Promise(executorOrPromise);

    this._process = result => {
    this._resolved = true;
    const then = this._queue.shift();
    if (then) {
    try {
    this._result = then(result);
    } catch (x) {
    _catch(x);
    return;
    }
    promise.then((...args) => {
    if(this.cancelled) reject('cancelled', ...args);
    else resolve(...args);
    });

    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);
    promise.catch(reject);
    });
    }

    cancel() {
    this.cancelled = true;
    this._queue = this._catches;
    this._resolved = true;
    this._caught = true;
    this._process({ cancelled: true });
    this.catch(noop);
    return this;
    }

    then(func) {
    this._thens.push(func);
    if (this._resolved && !this._caught) {
    this._process(this._result);
    }
    return this;
    return new CancellablePromise(this._promise.then(func));
    }

    catch(func) {
    this._catches.push(func);
    if (this._resolved && this._caught) {
    this._process(this._result);
    }
    return this;
    return new CancellablePromise(this._promise.catch(func));
    }
    }
  2. andyedinborough revised this gist Dec 20, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion CancellablePromise.js
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@ class CancellablePromise {

    this.cancelled = false;
    this._resolved = false;
    this._caught = true;
    this._caught = false;
    this._thens = [];
    this._catches = [];
    this._queue = this._thens;
  3. andyedinborough created this gist Dec 20, 2015.
    67 changes: 67 additions & 0 deletions CancellablePromise.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    class CancellablePromise {
    constructor(executorOrPromise) {
    let promise = executorOrPromise;
    if (!promise.then) promise = new Promise(executorOrPromise);

    this.cancelled = false;
    this._resolved = false;
    this._caught = true;
    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;
    }
    }