Skip to content

Instantly share code, notes, and snippets.

@DScheglov
Last active September 7, 2021 13:39
Show Gist options
  • Save DScheglov/0df8619d73234ce85dfb134727873238 to your computer and use it in GitHub Desktop.
Save DScheglov/0df8619d73234ce85dfb134727873238 to your computer and use it in GitHub Desktop.
const isThenable = value => typeof value?.then === "function";
const wrapHandler = (handler, resolve, reject) => resultOrError => {
try {
const handledResult = handler(resultOrError);
if (isThenable(handledResult)) {
handledResult.then(resolve, reject);
} else {
resolve(handledResult);
}
} catch (error) {
reject(error);
}
}
const deferred = fn => (...args) => setTimeout(() => fn(...args));
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
export default class CustomPromise {
#status = PENDING
#onFullfilled = []
#onRejected = []
#result = undefined
#error = undefined
#resolve = deferred(result => {
if (this.#status !== PENDING) return;
this.#status = FULFILLED;
this.#result = result;
this.#onFullfilled.forEach(handler => handler(result));
})
#reject = deferred(error => {
if (this.#status !== PENDING) return;
this.#status = REJECTED;
this.#error = error;
this.#onRejected.forEach(handler => handler(error));
})
constructor(runner) {
runner(this.#resolve, this.#reject);
}
then(onFullfilled, onRejected) {
return new CustomPromise((resolve, reject) => {
const resolveNewPromise =
typeof onFullfilled === "function"
? wrapHandler(onFullfilled, resolve, reject)
: resolve;
const rejectNewPromise =
typeof onRejected === "function"
? wrapHandler(onRejected, resolve, reject)
: reject;
if (this.#status === FULFILLED) {
resolveNewPromise(this.#result);
return;
}
if (this.#status === REJECTED) {
rejectNewPromise(this.#error);
return;
}
this.#onFullfilled.push(resolveNewPromise);
this.#onRejected.push(rejectNewPromise);
});
}
catch(onRejected) {
return this.then(undefined, onRejected);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment