Created
May 3, 2022 07:46
-
-
Save jaydenseric/2e9db5ab90bd92a3cf0a48f3ce87effa to your computer and use it in GitHub Desktop.
A JavaScript with TypeScript JSDoc solution for a deferred promise that can be externally resolved or rejected.
This file contains hidden or 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
// @ts-check | |
/** | |
* A deferred promise that can be externally resolved or rejected. | |
* @template [Resolves=void] What the promise resolves. | |
* @extends {Promise<Resolves>} | |
*/ | |
export default class Deferred extends Promise { | |
/** @typedef {(value: Resolves | PromiseLike<Resolves>) => void} Resolve */ | |
/** @typedef {(reason?: any) => void} Reject */ | |
constructor() { | |
/** @type {Resolve | undefined} */ | |
let _resolve; | |
/** @type {Reject | undefined} */ | |
let _reject; | |
super((resolve, reject) => { | |
_resolve = resolve; | |
_reject = reject; | |
}); | |
/** Resolves the promise. */ | |
this.resolve = /** @type {Resolve} */ (_resolve); | |
/** Rejects the promise. */ | |
this.reject = /** @type {Reject} */ (_reject); | |
} | |
static get [Symbol.species]() { | |
return Promise; | |
} | |
get [Symbol.toStringTag]() { | |
return "Deferred"; | |
} | |
} |
This file contains hidden or 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
// @ts-check | |
import Deferred from "./Deferred.mjs"; | |
const deferred = new Deferred(); | |
setTimeout(() => { | |
deferred.resolve(); | |
}, 1000); | |
// Has a void type. | |
const foo = await deferred; |
This file contains hidden or 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
// @ts-check | |
import Deferred from "./Deferred.mjs"; | |
const deferred = /** @type {Deferred<boolean>} */ (new Deferred()); | |
setTimeout(() => { | |
deferred.resolve( | |
// TS only allows a boolean here. | |
true | |
); | |
}, 1000); | |
// Has a boolean type. | |
const foo = await deferred; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
An alternative approach (where the
Deferred
class doesn’t extendPromise
for less complexity at the cost of slightly worse ergonomics) can be seen at https://gist.github.com/jaydenseric/13923f5ea130ad669f7d35c4aeec70ac .