Promise.allSettled – wenn ein einziger Fehlschlag nicht alles kippen darf
Promise.all bricht beim ersten Fehler ab und wirft alle anderen Ergebnisse weg. Für ein Dashboard aus fünf Quellen ist das genau falsch: Vier Kacheln könnten Daten zeigen, aber die Seite bleibt leer.
Promise.all ist die richtige Wahl, wenn du alle Ergebnisse brauchst: Fehlt eins, ist die Aufgabe gescheitert. Sobald aber Teilergebnisse wertvoll sind – ein Dashboard, eine Übersicht aus mehreren APIs, ein Import aus vielen Dateien –, ist der Abbruch beim ersten Fehler schädlich.
// Eine kaputte Quelle, und der ganze Aufruf wirft:
const [a, b, c] = await Promise.all([hole('/a'), hole('/b'), hole('/c')]);allSettled wartet auf alle – und erzählt, wie es ausging
const ergebnisse = await Promise.allSettled([
hole('/api/wetter'),
hole('/api/termine'),
hole('/api/umsatz'),
]);
// [
// { status: 'fulfilled', value: {...} },
// { status: 'rejected', reason: Error('500') },
// { status: 'fulfilled', value: {...} },
// ]Die Reihenfolge entspricht immer der Eingabe – auch wenn die dritte Anfrage als erste fertig war.
Ergebnisse und Fehler trennen
const daten = ergebnisse.filter(e => e.status === 'fulfilled').map(e => e.value);
const fehler = ergebnisse.filter(e => e.status === 'rejected').map(e => e.reason);
if (fehler.length) {
console.warn(`${fehler.length} von ${ergebnisse.length} Quellen nicht erreichbar`, fehler);
}
zeigeDashboard(daten);Wichtig für die Oberfläche: Zeig die Kacheln, die Daten haben, und markier die übrigen ausdrücklich als „gerade nicht erreichbar". Ein leeres Feld ohne Erklärung ist schlimmer als eine ehrliche Meldung.
Mit Namen statt Positionen
Bei mehr als drei Quellen wird das Abzählen über den Index schnell fehleranfällig:
const quellen = { wetter: '/api/wetter', termine: '/api/termine', umsatz: '/api/umsatz' };
const namen = Object.keys(quellen);
const roh = await Promise.allSettled(namen.map(n => hole(quellen[n])));
const stand = Object.fromEntries(
namen.map((n, i) => [n, roh[i].status === 'fulfilled' ? roh[i].value : null])
);
if (stand.umsatz === null) zeigeHinweis('Umsatzzahlen sind gerade nicht verfügbar.');Die Verwandtschaft in einem Satz
Promise.all– alle müssen klappen, bricht beim ersten Fehler ab.Promise.allSettled– wartet auf alle, meldet je Eintrag Erfolg oder Fehler.Promise.any– der erste Erfolg gewinnt, Fehler werden ignoriert (gut für Spiegelserver).Promise.race– das erste Ergebnis gewinnt, egal ob Erfolg oder Fehler (gut für Zeitlimits).
Fallstrick
allSettled lehnt nie ab – und genau deshalb verschluckt es Fehler, wenn du die rejected-Einträge nicht ausliest. Prüfe sie immer, protokolliere sie, und denk daran: Ein fetch, das mit Status 500 antwortet, ist für JavaScript ein erfolgreiches Promise. Wirf im Lade-Helfer selbst, wenn response.ok falsch ist, sonst landen Serverfehler fröhlich im fulfilled-Topf.
Wenn du eine Oberfläche brauchst, die auch mit halb erreichbaren Diensten sauber umgeht: bymw.de.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
Formulare ohne Neuladen abschicken – FormData und fetch
Ein Formular per JavaScript abzuschicken heißt nicht, jedes Feld einzeln auszulesen. FormData nimmt das ganze Formular, fetch schickt es weg – inklusive Dateien, und mit einer Fehlermeldung, die der Besucher versteht.
Web Worker – rechnen, ohne die Oberfläche einzufrieren
JavaScript hat im Browser genau einen Faden für alles: Klicks, Animationen, Layout – und deine Rechenschleife. Dauert die zwei Sekunden, ist die Seite zwei Sekunden lang tot. Ein Worker nimmt die Arbeit auf einen eigenen Faden.
CustomEvent – Bausteine, die sich gegenseitig Bescheid sagen, ohne sich zu kennen
Sobald zwei Teile einer Seite aufeinander reagieren sollen, landet man schnell bei globalen Variablen oder Funktionsaufrufen quer durchs Projekt. Eigene Events entkoppeln das – mit denselben Mitteln, die der Browser selbst benutzt.