Created
July 18, 2023 17:57
-
-
Save lmammino/ef121da874a80d657379a1cd64bf8166 to your computer and use it in GitHub Desktop.
Promise.withResolvers() polyfill
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
| if (typeof Promise.withResolvers === 'undefined') { | |
| Promise.withResolvers = function () { | |
| let resolve, reject | |
| const promise = new Promise((res, rej) => { | |
| resolve = res | |
| reject = rej | |
| }) | |
| return { promise, resolve, reject } | |
| } | |
| } | |
| // Usage: | |
| // const { promise, resolve, reject } = Promise.withResolvers() | |
| // console.log(promise, resolve, reject) // Promise { <pending> } [Function (anonymous)] [Function (anonymous)] | |
| // ... Do something async and then call resolve or reject! |
@lmammino this is not working:
Object.assign(Promise, { withResolvers: () => { let resolve; let reject; const promise = new Promise((resolve, reject) => { resolve = resolve; reject = reject; }); return { promise, resolve, reject }; }}); const a = Promise.withResolvers() a.promise.then(() => console.log('resolved')) a.resolve();With this error:
VM717:20 Uncaught TypeError: a.resolve is not a function at <anonymous>:20:3But I see that it is because of the name that I am reassigning the variable inside the function, not the one outside. It's totally my fault. Sorry about that.
bruh 🙈
For anyone that wants a ts version.
looked at bun https://bun.com/reference/globals/PromiseConstructor/withResolvers
something that stood out was that in bun the resolve prop is of type (value?: T | PromiseLike<T>) => void;
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (Promise.withResolvers === undefined) {
function __withResolvers<T, E = unknown>(): PromiseWithResolvers<T, E> {
let resolve: PromiseWithResolvers<T,E>["resolve"];
let reject: PromiseWithResolvers<T, E>["reject"];
const promise = new Promise<T>((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve: resolve!, reject: reject! };
}
Object.defineProperty(Promise, "withResolvers", {
value: __withResolvers,
writable: false,
configurable: false,
enumerable: false
});
}
declare global {
export type PromiseWithResolvers<T, E = unknown> = {
promise: Promise<T>;
resolve: (value: T | PromiseLike<T>) => void;
reject: (reason?: E) => void;
};
interface PromiseConstructor {
/**
* Create a deferred promise, with exposed resolve and reject methods
* which can be called separately.
* This is useful when you want to return a Promise
* and have code outside the Promise resolve or reject it.
*/
withResolvers<T>(): PromiseWithResolvers<T>;
/**
* Creates a new Promise and returns it in an object, along with its resolve and reject functions.
*
* @returns {PromiseWithResolvers<T>} An object with the properties promise, resolve, and reject.
*/
withResolvers<T, E = unknown>(): {
promise: Promise<T>;
resolve: (value: T | PromiseLike<T>) => void;
reject: (reason?: E) => void;
};
}
}
export {};
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks, @WORMSS! I was not aware :)