51 lines
1.1 KiB
TypeScript
51 lines
1.1 KiB
TypeScript
type OptionalArgs<T> =
|
|
| {
|
|
saveInCache: (result: NonNullable<T>) => Promise<void>;
|
|
fetchFromCache: () => Promise<T | null | undefined>;
|
|
}
|
|
| {
|
|
saveInCache?: undefined;
|
|
fetchFromCache?: undefined;
|
|
};
|
|
|
|
interface FetchFromMultipleSourcesResult<T> {
|
|
result: T | null;
|
|
errorOccurred: boolean;
|
|
}
|
|
|
|
export async function fetchFromMultipleSources<T>(
|
|
fetchPromises: (() => Promise<T | null | undefined>)[],
|
|
args?: OptionalArgs<T>,
|
|
): Promise<FetchFromMultipleSourcesResult<T>> {
|
|
let result = await args?.fetchFromCache?.();
|
|
if (result) {
|
|
return { result, errorOccurred: false };
|
|
}
|
|
|
|
if (fetchPromises.length === 0) {
|
|
throw new Error("fetchPromises cannot be empty");
|
|
}
|
|
|
|
let errorCount = 0;
|
|
for (let i = 0; i < fetchPromises.length; i++) {
|
|
const promise = fetchPromises[i];
|
|
try {
|
|
result = await promise();
|
|
if (result) break;
|
|
} catch (e) {
|
|
console.error(e);
|
|
errorCount++;
|
|
}
|
|
}
|
|
|
|
if (args?.saveInCache && result) {
|
|
await args.saveInCache(result);
|
|
}
|
|
|
|
result = result ?? null;
|
|
return {
|
|
result,
|
|
errorOccurred: errorCount === fetchPromises.length,
|
|
};
|
|
}
|