Was ist Promise?
Promise ist ein Objekt, das das Ergebnis einer asynchronen Operation darstellt, die jetzt, in der Zukunft oder nie erhalten werden kann. Dies ist eine Art "Versprechen", das Ergebnis zurückzugeben, wenn die Operation abgeschlossen ist.
Promis existiert in einem von drei Zuständen:
pending (Warten) — Anfangszustand, Vorgang wird noch ausgeführt
fulfilled (abgeschlossen) — Vorgang erfolgreich abgeschlossen
rejected (abgelehnt) — Operation mit Fehler beendet
Es ist wichtig zu verstehen, dass ein Versprechen nur einmal aus dem Status pending in den Status fulfilled oder rejected übergehen kann. Danach ändert sich der Status nicht mehr.
Erstellen eines Versprechens
Ein Promis wird mit dem Konstruktor Promise erstellt, der eine Executor-Funktion akzeptiert. Diese Funktion erhält zwei Argumente: resolve und reject.
const myPromise = new Promise((resolve, reject) => {
// Asynchrone Operation
const success = true;
if (success) {
resolve('The operation was successful!');
} else {
reject('An error occurred');
}
});Die Executor-Funktion wird sofort gestartet, wenn ein Promis erstellt wird. Wenn Sie resolve(value) aufrufen, wechselt das Versprechen in den Zustand fulfilled mit dem Ergebnis value. Beim Aufruf von reject(error) geht das Promis mit dem Fehler error in rejected über.
Ergebnisverarbeitung: then, catch, finally
Die Methoden then, catch und finally werden verwendet, um mit dem Ergebnis des Promises zu arbeiten.
myPromise
.then(result => {
console.log('Success:', result);
return result.toUpperCase();
})
.catch(error => {
console.error('Error:', error);
})
.finally(() => {
console.log('Operation completed');
});Die Methode then akzeptiert zwei optionale Argumente: einen Callback für eine erfolgreiche Ausführung und einen Callback für einen Fehler. In der Praxis wird catch häufiger verwendet, um Fehler zu behandeln, was den Code lesbarer macht.
Die Methode finally wird immer ausgeführt, unabhängig vom Ergebnis des Versprechens. Dies ist praktisch für Aktionen, die in jedem Fall ausgeführt werden müssen, z. B. das Ausblenden der Ladeanzeige.
Promis-Ketten
Einer der Hauptvorteile von Promises ist die Möglichkeit, Ketten asynchroner Operationen zu erstellen. Jeder then gibt ein neues Versprechen zurück, mit dem Sie Sequenzen erstellen können.
fetch('https://api.example.com/user/1')
.then(response => response.json())
.then(user => {
console.log('Username:', user.name);
return fetch(`https://api.example.com/user/${user.id}/posts`);
})
.then(response => response.json())
.then(posts => {
console.log('User posts:', posts);
})
.catch(error => {
console.error('Error in the chain:', error);
});In der Kette der Promises "fällt" ein Fehler in jeder Phase bis zum nächsten catch. Auf diese Weise können Fehler zentral behandelt werden.

Praktisches Beispiel: Daten laden
Betrachten wir ein reales Szenario - das Laden von Benutzerdaten vom Server mit der Verarbeitung verschiedener Situationen.
function fetchUserData(userId) {
return new Promise((resolve, reject) => {
// Simulation von Netzwerkverzögerungen
setTimeout(() => {
const users = {
1: { name: 'Alexey', role: 'developer' },
2: { name: 'Maria', role: 'designer' }
};
const user = users[userId];
if (user) {
resolve(user);
} else {
reject(new Error('User not found'));
}
}, 1000);
});
}
// Anwendung
fetchUserData(1)
.then(user => {
console.log(`Hi ${user.name}!`);
console.log(`Your role: ${user.role}`);
})
.catch(error => {
console.error('Failed to load data:', error.message);
})
.finally(() => {
console.log('Request completed');
});Promise.all und Promise.race
JavaScript bietet nützliche statische Methoden für die Arbeit mit mehreren Promises.
Promise.all
Die Methode Promise.all nimmt ein Array von Promises an und gibt ein neues Promise zurück, das ausgeführt wird, wenn alle Promises im Array ausgeführt wurden. Wenn mindestens ein Versprechen abgelehnt wird, wird der gesamte Promise.all abgelehnt.
const promise1 = Promise.resolve(3);
const promise2 = new Promise(resolve => setTimeout(() => resolve(42), 1000));
const promise3 = fetch('https://api.example.com/data').then(r => r.json());
Promise.all([promise1, promise2, promise3])
.then(results => {
console.log('All results:', results);
// results wird ein Array sein: [3, 42, {...Daten aus der API}]
})
.catch(error => {
console.error('One of the promisses ended in error:', error);
});Dies ist nützlich, wenn Sie mehrere unabhängige asynchrone Operationen ausführen und auf alle warten müssen.
Promise.race
Die Methode Promise.race gibt ein Versprechen zurück, das ausgeführt oder abgelehnt wird, sobald das erste der übergebenen Versprechen ausgeführt oder abgelehnt wird.
const slowPromise = new Promise(resolve =>
setTimeout(() => resolve('Slow'), 3000)
);
const fastPromise = new Promise(resolve =>
setTimeout(() => resolve('Fast'), 1000)
);
Promise.race([slowPromise, fastPromise])
.then(result => {
console.log('Winner:', result); // 'Schnell'});Dies ist nützlich, um Timeouts zu implementieren oder die schnellste Datenquelle auszuwählen.
Promise.allSettled und Promise.any
Moderne Versionen von JavaScript haben zwei weitere nützliche Methoden hinzugefügt.
Promise.allSettled
Im Gegensatz zu Promise.all wartet die Methode Promise.allSettled unabhängig vom Ergebnis auf den Abschluss aller Promises. Gibt ein Array von Objekten mit Informationen zu jedem Versprechen zurück.
const promises = [
Promise.resolve('Success'),
Promise.reject('Error'),
Promise.resolve('More success')
];
Promise.allSettled(promises)
.then(results => {
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Promis ${index}: executed with value ${result.value}`);
} else {
console.log(`Promo ${index}: rejected with reason ${result.reason}`);
}
});
});Promise.any
Die Methode Promise.any gibt die erste erfolgreich ausgeführte Promesse zurück. Wenn alle Promises abgelehnt werden, wird das abgelehnte Promise mit einem aggregierten Fehler zurückgegeben.
const promises = [
Promise.reject('Error 1'),
Promise.resolve('Success'),
Promise.reject('Error 2')
];
Promise.any(promises)
.then(result => {
console.log('First successful result:', result); // 'Erfolg's'
})
.catch(error => {
console.error('All promissory notes are rejected:', error);
});Typische Fehler bei der Arbeit mit Promises
Vergessene Rückgabe in der Kette
Einer der häufigsten Fehler ist, zu vergessen, den Prom aus then zurückzugeben, was die Kette unterbricht.
// Falsch
fetchUser()
.then(user => {
fetchPosts(user.id); // Sie haben die Rückgabe vergessen!
})
.then(posts => {
// Beiträge werden nicht definiert
console.log(posts);
});
// Richtig
fetchUser()
.then(user => {
return fetchPosts(user.id); // Wir geben die Prämie zurück
})
.then(posts => {
console.log(posts); // Posts enthält jetzt Daten
});Verschachtelte Promises anstelle von Ketten
Manchmal erstellen Entwickler verschachtelte Promises, was uns zum Problem des Callback-Hells zurückführt.
// Schlecht - Verschachtelung
fetchUser()
.then(user => {
fetchPosts(user.id)
.then(posts => {
fetchComments(posts[0].id)
.then(comments => {
console.log(comments);
});
});
});
// Gut — Kette
fetchUser()
.then(user => fetchPosts(user.id))
.then(posts => fetchComments(posts[0].id))
.then(comments => console.log(comments))
.catch(error => console.error(error));Fehlende Fehlerbehandlung
Fügen Sie immer catch hinzu, um Fehler zu behandeln, da sie sonst möglicherweise nicht bemerkt werden.
// Gefährlich
fetchData().then(data => console.log(data));
// Sicher
fetchData()
.then(data => console.log(data))
.catch(error => console.error('An error occurred:', error));Von Promises zu Async/Await
Promises legten den Grundstein für die Syntax von async/await, die asynchronen Code noch synchroner macht.
// Mit Versprechen
function getUserInfo() {
return fetchUser()
.then(user => fetchPosts(user.id))
.then(posts => {
return { user, posts };
});
}
// Mit async/await
async function getUserInfo() {
const user = await fetchUser();
const posts = await fetchPosts(user.id);
return { user, posts };
}Das Verständnis von Promises ist jedoch von entscheidender Bedeutung, da async/await ein syntaktischer Zucker für Promises ist und das Wissen über ihre Funktionsweise hilft, Asynchronität in JavaScript effektiv zu nutzen.
Befund
Promises lösen ein grundlegendes Problem von JavaScript - die elegante Arbeit mit asynchronen Operationen. Sie bieten eine intuitive Schnittstelle für die Steuerung von Aktionssequenzen, die Fehlerbehandlung und die Zusammensetzung asynchroner Operationen.
Wichtige Punkte, die man sich merken sollte:
Promis befindet sich in einem von drei Zuständen und ändert ihn nur einmal
Promises-Ketten lösen das Problem der Callback-Verschachtelung
Behandeln Sie Fehler immer mit catch
Verwenden Sie Promise.all, um unabhängige Operationen parallel auszuführen
Geben Sie die Promises von then zurück, um die richtigen Ketten zu erstellen
Ein tiefes Verständnis von Promises ist die Grundlage für die Arbeit mit modernem asynchronem JavaScript und den Übergang zu async/await.
Möchten Sie Ihr Wissen systematisieren? Auf der Plattform Kodik finden Sie praktische Programmierkurse mit Zertifikat nach Abschluss der Ausbildung.
Schließen Sie sich unserem gemütlicher Telegram-Kanal — Hier teilen wir nützliche Materialien, diskutieren interessante Themen und helfen Entwicklerneulingen, sich beruflich weiterzuentwickeln. Gemeinsam lernt es sich besser!
