, der dies genau beschreibt, ist genau Schwierig, also tragen Sie es mit mir
Ich habe eine Karte mit Versprechen, z. B.:
Code: Select all
const namedPromises = {
database: promise1 as Promise,
someApi: promise2 as Promise,
// ...
} as Record;
< /code>
Der Anwendungsfall dafür ist die Gesundheitsberichterstattung für einen Dienst (denken Sie an, A /Health < /code> Endpunkt zu rufen und andere Endpunkte /Abhängigkeiten für ihre Gesundheit aufzurufen )
Und ich möchte es in ein Versprechen umwandeln
Code: Select all
function async someMethod(namedPromises: Record): Promise {
// ...magic...
// i know the result will be more generic but this is for example's sake.
return {
database: promiseSettled1 as PromiseSettledResult,
someApi: promiseSettled2 as PromiseSettledResult,
};
}
Ich gebe einen Schlüssel mit beiden gelöst. und lehnte Ergebnisse ab, um zu wissen, auf welches Versprechen es sich bezieht.
Code: Select all
const wrapped = Object.entries(namedPromises).map(([key, promise]) => {
return promise.then(
(value) => ({
key,
result: {
status: 'fulfilled',
value,
} as PromiseFulfilledResult,
}),
(reason) => ({
key,
result: {
status: 'rejected',
reason,
},
}),
);
});
< /code>
Hier in liegt das Hauptproblem. Dieses Meta -Ergebnis ist auch ein Versprechen
Code: Select all
key
Ich denke Ich kann dieses Gefühl mit Beweisen nicht rechtfertigen.
Code: Select all
wrapped
Hier ist meine aktuelle Lösung vollständig, einschließlich Timeouts:
Code: Select all
async allSettledDependencies(
dependencyHealthReporters: Record,
timeoutPerDependency: number = 1000, // ms
): Promise {
const withTimeout = (
key: string,
promise: Promise,
): Promise => {
const timeoutPromise = new Promise((_, reject) =>
setTimeout(
() =>
reject(new Error(`Timeout exceeded: ${timeoutPerDependency}ms`)),
timeoutPerDependency,
),
);
// allow dependencies to timeout individually to increase resilience of health function.
return Promise.race([promise, timeoutPromise]).then(
(value) => ({
key,
result: {
status: 'fulfilled',
value,
} as PromiseFulfilledResult,
}),
// this will be either the timeout rejection, or the rejected promise.
(reason) => ({
key,
result: {
status: 'rejected',
reason,
},
}),
) as Promise;
};
const settledEntries = await Promise.allSettled(
Object.entries(dependencyHealthReporters).map(
([dependencyName, promise]) => withTimeout(dependencyName, promise),
),
);
return Object.fromEntries(
settledEntries
// we rely on all promises being fulfilled at the `withTimeout` function for this logic to work.
.filter((topSettled) => topSettled.status === 'fulfilled')
.map(({ value }) => [
value.key,
// either returns the resolved health info or converts the rejection error into an
this.healthInfoFromSettledResult(value.result),
]),
);
}
< /code>
Einige verwandte Gedanken: < /p>
[u]
[*] Gibt es eine Möglichkeit zu sagen: "Vertrauen Sie mir, Bruder, diese alles lösen?" Außer so unbekannt wie versprochen erfüllt
[*] Ich könnte Promise nennen > Wenn ich zuversichtlich über die marituruierte Siedlung der verpackten Versprechen bin, fühlt sich etwas daran ein.
[/u]