Skip to content

Instantly share code, notes, and snippets.

@jesusgoku
Created January 26, 2023 01:03
Show Gist options
  • Save jesusgoku/dc55dcd0620e71f74dc158d85142d498 to your computer and use it in GitHub Desktop.
Save jesusgoku/dc55dcd0620e71f74dc158d85142d498 to your computer and use it in GitHub Desktop.
Implementation of Promise static methods
function promisesAll(promisesCollection) {
return new Promise((resolve, reject) => {
const resolved = [];
promisesCollection.forEach((promise, index) => {
promise
.then((value) => {
resolved.push({ index, value });
if (resolved.length === promisesCollection.length) {
resolve(restoreArray(resolved));
}
})
.catch((err) => {
reject(err);
});
});
});
}
function promisesAny(promisesCollection) {
return new Promise((resolve, reject) => {
const rejected = [];
promisesCollection.forEach((promise, index) => {
promise
.then((value) => {
resolve(value);
})
.catch((err) => {
rejected.push({ index, value: err });
if (rejected.length === promisesCollection.length) {
reject(new AggregateError(restoreArray(rejected)));
}
});
});
});
}
function promisesAllSettled(promisesCollection) {
return new Promise((resolve) => {
const state = [];
promisesCollection.forEach((promise, index) => {
promise
.then((value) => {
state.push({
index,
value: {
status: 'fulfilled',
value,
},
});
})
.catch((reason) => {
state.push({
index,
value: {
status: 'rejected',
reason,
},
});
})
.then(() => {
if (state.length === promisesCollection.length) {
resolve(restoreArray(state));
}
});
});
});
}
function promisesRace(promisesCollection) {
return new Promise((resolve, reject) => {
let isSettled = false;
promisesCollection.forEach((promise) => {
promise
.then((value) => {
if (isSettled) return;
isSettled = true;
resolve(value);
})
.catch((err) => {
if (isSettled) return;
isSettled = true;
reject(err);
});
});
});
}
function promisesSomeCount(promisesCollection, count) {
return new Promise((resolve, reject) => {
const resolved = [];
const rejected = [];
promisesCollection.forEach((promise) => {
promise
.then((value) => {
resolved.push(value);
if (resolved.length === count) {
resolve(resolved);
}
})
.catch((err) => {
rejected.push(err);
if (rejected.length > promisesCollection.length - count) {
reject(new AggregateError(rejected))
}
});
});
});
}
function restoreArray(collection) {
return collection.reduce((acc, { index, value }) => {
acc[index] = value;
return acc;
}, []);
}
class MyOwnPromise {
static all(promises) { return promisesAll(promises); }
static any(promises) { return promisesAny(promises); }
static allSettled(promises) { return promisesAllSettled(promises); }
static race(promises) { return promisesRace(promises); }
static someCount(promises, count) { return promisesSomeCount(promises, count); }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment