Skip to content

Instantly share code, notes, and snippets.

@wangziling
Created February 6, 2023 03:39
Show Gist options
  • Save wangziling/8fee6588136026a8418be6f653c72d69 to your computer and use it in GitHub Desktop.
Save wangziling/8fee6588136026a8418be6f653c72d69 to your computer and use it in GitHub Desktop.
Promise.allSettled
export type TPromiseAllSettledParam<F = any, R = any> =
Array<Promise<F> | F>
| Record<string, Promise<F> | F>;
export type TPromiseAllSettledReturnValue<F, R> = Promise<Array<IPromiseAllSettledFulfilledResult<F> | IPromiseAllSettledRejectedResult<R>>>;
export interface IPromiseAllSettledFulfilledResult<F = any> {
status: EPromiseAllSettledStatus.fulfilled,
value: F
}
export interface IPromiseAllSettledRejectedResult<R = Error> {
status: EPromiseAllSettledStatus.rejected,
reason: R
}
export enum EPromiseAllSettledStatus {
pending = 'pending', // Will never be used. Just record.
fulfilled = 'fulfilled',
rejected = 'rejected'
}
export type TPromiseFulfilledResult<T> = T extends Promise<infer P> ? P : never;
/**
* The polyfill about `Promise.allSettled`.
* @param promiseIterator {TPromiseAllSettledParam<any, Error>}
* @return {Promise<any[]>}
*/
export function promiseAllSettled<F = any, R = Error>(
promiseIterator: TPromiseAllSettledParam<F, R>
): TPromiseAllSettledReturnValue<F, R> {
return new Promise(resolve => {
const iteratorArr = Object.values(promiseIterator);
let len = iteratorArr.length;
const result: TPromiseFulfilledResult<TPromiseAllSettledReturnValue<F, R>> = new Array(len);
if (!len) return resolve(result);
iteratorArr.forEach((iterator, index) => {
Promise.resolve(iterator)
.then(value => {
return result[index] = {
status: EPromiseAllSettledStatus.fulfilled,
value
};
})
.catch(reason => {
return result[index] = {
status: EPromiseAllSettledStatus.rejected,
reason
};
})
.finally(() => {
len--;
// If all executed and got the result or reason.
if (!len) {
return resolve(result);
}
});
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment