Skip to content

Instantly share code, notes, and snippets.

@carefree-ladka
Created August 14, 2023 10:02
Show Gist options
  • Select an option

  • Save carefree-ladka/f19fa9076ac7c16651f22cc58f6dc5aa to your computer and use it in GitHub Desktop.

Select an option

Save carefree-ladka/f19fa9076ac7c16651f22cc58f6dc5aa to your computer and use it in GitHub Desktop.
Promise Polyfill in JavaScript
export default class MyPromise {
constructor(executor) {
let resolved = false;
let rejected = false;
let resolveValue;
let rejectValue;
let resolveCallbacks = [];
let rejectCallbacks = [];
function resolve(value) {
if (resolved || rejected) return;
resolved = true;
resolveValue = value;
resolveCallbacks.forEach((fn) => fn(value));
}
function reject(reason) {
if (resolved || rejected) return;
rejected = true;
rejectValue = reason;
rejectCallbacks.forEach((fn) => fn(reason));
}
this.then = function (onResolve, onReject) {
if (resolved) {
onResolve(resolveValue);
} else if (rejected) {
onReject(rejectValue);
} else {
resolveCallbacks.push(onResolve);
rejectCallbacks.push(onReject);
}
return this;
};
this.catch = function (onReject) {
if (rejected) {
onReject(rejectValue);
} else {
rejectCallbacks.push(onReject);
}
return this;
};
executor(resolve, reject);
}
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach((promise) => {
promise.then(resolve).catch(reject);
});
});
}
static any(promises) {
return new MyPromise((resolve, reject) => {
let rejectedCount = 0;
const errors = [];
promises.forEach((promise) => {
promise.then(resolve).catch((error) => {
errors.push(error);
rejectedCount++;
if (rejectedCount === promises.length) {
reject(new AggregateError(errors, "All promises were rejected"));
}
});
});
});
}
static all(promises) {
return new MyPromise((resolve, reject) => {
const results = new Array(promises.length);
let resolvedCount = 0;
promises.forEach((promise, index) => {
promise
.then((result) => {
results[index] = result;
resolvedCount++;
if (resolvedCount === promises.length) {
resolve(results);
}
})
.catch(reject);
});
});
}
static allSettled(promises) {
return new MyPromise((resolve) => {
const results = new Array(promises.length);
let settledCount = 0;
promises.forEach((promise, index) => {
promise
.then((result) => {
results[index] = { status: "fulfilled", value: result };
})
.catch((error) => {
results[index] = { status: "rejected", reason: error };
})
.finally(() => {
settledCount++;
if (settledCount === promises.length) {
resolve(results);
}
});
});
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment