Created
March 7, 2018 03:00
-
-
Save jaredcnance/6f0d5fa3d4a92910c96270cdf177f391 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import CancellablePromise from '../CancellablePromise'; | |
import Sleep from '../../../test/tools/Sleep'; | |
describe('CancellablePromise', () => { | |
it('can be awaited', async () => { | |
let completed = false; | |
let basePromise = new Promise(resolve => { | |
setTimeout(resolve, 200); | |
}).then(() => (completed = true)); | |
let cancellablePromise = new CancellablePromise(basePromise); | |
await cancellablePromise; | |
expect(completed).toEqual(true); | |
}); | |
it('does not block if it is not awaited', async () => { | |
let completed = false; | |
let basePromise = new Promise(resolve => { | |
setTimeout(resolve, 200); | |
}).then(() => (completed = true)); | |
let cancellablePromise = new CancellablePromise(basePromise); | |
cancellablePromise; | |
expect(completed).toEqual(false); | |
}); | |
it('can be cancelled', async () => { | |
let completed = false; | |
let basePromise = new Promise(resolve => { | |
setTimeout(resolve, 200); | |
}); | |
let cancellablePromise = new CancellablePromise(basePromise); | |
cancellablePromise.then(() => (completed = true)); | |
cancellablePromise.cancel(); | |
await Sleep(200); | |
expect(completed).toEqual(false); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default class CancellablePromise<T> { | |
private resolver: (value?: T | PromiseLike<T>) => void; | |
private rejecter: (reason?: any) => void; | |
private readonly promise: Promise<T>; | |
private hasCanceled = false; | |
/** | |
* Creates an instance of CancellablePromise. | |
* | |
* @param {Promise<T>} innerPromise the underlying promise to be cancelled | |
* | |
* @memberOf CancellablePromise | |
*/ | |
constructor(innerPromise: Promise<T>) { | |
this.promise = new Promise((resolve, reject) => { | |
this.resolver = resolve; | |
this.rejecter = reject; | |
}); | |
innerPromise.then( | |
val => | |
this.hasCanceled | |
? this.reject({ isCanceled: true }) | |
: this.resolve(val), | |
error => | |
this.hasCanceled | |
? this.reject({ isCanceled: true }) | |
: this.reject(error), | |
); | |
} | |
then( | |
onfulfilled?: (value: T) => T | PromiseLike<T>, | |
onrejected?: (reason: any) => PromiseLike<never>, | |
): Promise<T> { | |
return this.promise.then(onfulfilled, onrejected); | |
} | |
catch(onRejected?: (reason: any) => PromiseLike<never>): Promise<T> { | |
return this.promise.catch(onRejected); | |
} | |
private resolve(value?: T | PromiseLike<T>): void { | |
return this.resolver(value); | |
} | |
private reject(reason?: any): void { | |
return this.rejecter(reason); | |
} | |
cancel() { | |
this.hasCanceled = true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment