Skip to content

Instantly share code, notes, and snippets.

@jaydenseric
Created May 3, 2022 07:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaydenseric/2e9db5ab90bd92a3cf0a48f3ce87effa to your computer and use it in GitHub Desktop.
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.
// @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";
}
}
// @ts-check
import Deferred from "./Deferred.mjs";
const deferred = new Deferred();
setTimeout(() => {
deferred.resolve();
}, 1000);
// Has a void type.
const foo = await deferred;
// @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;
@jaydenseric
Copy link
Author

An alternative approach (where the Deferred class doesn’t extend Promise for less complexity at the cost of slightly worse ergonomics) can be seen at https://gist.github.com/jaydenseric/13923f5ea130ad669f7d35c4aeec70ac .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment