I have come up with a function that is supposed to take an array of Promises and only return the resolved ones while ignoring any errors. It's similar to Promise.all but without considering errors. The challenge is implementing this function correctly in TypeScript. Previously, when I was using just JavaScript, I expected the desired results.
function promiseIgnoreErrors<T> (arrayOfPromise: Array<T>) {
const isArrayEmpty =
Array.isArray(arrayOfPromise) && arrayOfPromise.length === 0;
return new Promise((resolve, reject) => {
if (isArrayEmpty) reject(new Error('Forever pending array'));
let resolvedArray: Array<T> = []
let resolvedCounter: number = 0;
arrayOfPromise.forEach((promise, index) => {
if (promise instanceof Promise) {
promise
.then((data) => {
resolvedArray[index] = data
resolvedCounter++;
if (arrayOfPromise.length === resolvedCounter) resolve(resolvedArray)
})
.catch(() => {
resolvedCounter++;
if (arrayOfPromise.length === resolvedCounter) resolve(resolvedArray)
})
} else {
resolvedArray[index] = promise
resolvedCounter++;
if (arrayOfPromise.length === resolvedCounter) resolve(resolvedArray)
}
})
});
};
Here is a brief overview of my problem along with some sample variables:
const p1 = new Promise((resolve) => setTimeout(() => resolve('JS'), 500))
const p2 = 22
const p3 = new Promise((reject) => setTimeout(() => reject(new Error('Oops')), 100))
const p4 = new Promise((resolve) => setTimeout(() => resolve('TS'), 200))
When I pass these variables as an array,
promiseIgnoreErrors([p1, p2, p3, Promise.reject(10), p4])
I expect to get:
Promise {<pending>}
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Array(3)
// ['JS', 22, 'TS']
However, the actual output is:
Promise {<pending>}
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Array(5)
// ['JS', 22, Error: 'Oops, ?, 'TS']
You can see this issue in action here: Playground
I suspect the issue lies with the generic type and specifically this line:
let resolvedArray: Array<T> = []
because it suggests that the returned array must consist of the same elements as the input. Maybe it should be something like:
let resolvedArray: Array<K> extends T = []
While I know the above line is incorrect, maybe following this idea could lead to a solution.. Or perhaps there's another flaw in my function?
I would appreciate any help!