Skip to content

Türchen 05

Published: at 07:00 AMSuggest Changes

Promises – Bessere Handhabung von asynchronem Code

Die asynchrone Programmierung ist ein wesentlicher Bestandteil von JavaScript, insbesondere bei Operationen wie Netzwerkaufrufen, Dateisystemzugriffen oder Timern. Vor der Einführung von Promises in ES6 (ECMAScript 2015) wurden asynchrone Operationen hauptsächlich mit Callbacks gehandhabt, was oft zu unübersichtlichem und schwer wartbarem Code führte (bekannt als “Callback Hell”). Promises bieten eine elegantere und strukturiertere Methode, um mit asynchronem Code umzugehen.

Was sind Promises?

Ein Promise ist ein Objekt, das einen Wert repräsentiert, der jetzt, später oder nie verfügbar sein wird. Es handelt sich um einen Platzhalter für das Ergebnis einer asynchronen Operation. Ein Promise kann sich in einem von drei Zuständen befinden:

Ein einfaches Beispiel

Angenommen, wir haben eine Funktion, die Daten von einer API abruft:

function fetchData(callback) {
  setTimeout(() => {
    const data = { name: 'Max', age: 30 };
    callback(data);
  }, 1000);
}

fetchData((data) => {
  console.log(data);
});

Mit Callbacks kann dieser Code bei komplexeren Szenarien schnell unübersichtlich werden.

Mit Promises können wir denselben Code strukturierter schreiben:

function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = { name: 'Max', age: 30 };
      resolve(data);
      // Bei einem Fehler würde man reject(error) aufrufen
    }, 1000);
  });
}

fetchData()
  .then((data) => {
    console.log(data); // { name: 'Max', age: 30 }
  })
  .catch((error) => {
    console.error('Fehler:', error);
  });

Aufbau eines Promises

Ein Promise wird mit dem new Promise Konstruktor erstellt, der eine Funktion (executor) akzeptiert. Diese Funktion erhält zwei Argumente:

Beispiel:

const myPromise = new Promise((resolve, reject) => {
  // Asynchrone Operation
  const success = true;

  if (success) {
    resolve('Operation erfolgreich!');
  } else {
    reject('Operation fehlgeschlagen!');
  }
});

Verwendung von then und catch

Promises bieten die Methoden then und catch, um auf die Auflösung oder Ablehnung zu reagieren.

Beispiel:

myPromise
  .then((message) => {
    console.log(message); // 'Operation erfolgreich!'
  })
  .catch((error) => {
    console.error(error); // 'Operation fehlgeschlagen!'
  });

Verkettung von Promises

Einer der großen Vorteile von Promises ist die Möglichkeit, sie zu verketten. Das ermöglicht das sequentielle Ausführen von asynchronen Operationen.

Beispiel:

function firstOperation() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('Erste Operation abgeschlossen.');
      resolve(1);
    }, 1000);
  });
}

function secondOperation(result) {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('Zweite Operation abgeschlossen.');
      resolve(result + 1);
    }, 1000);
  });
}

firstOperation()
  .then((result) => {
    return secondOperation(result);
  })
  .then((finalResult) => {
    console.log('Endergebnis:', finalResult); // Endergebnis: 2
  });

Parallelisierung mit Promise.all

Mit Promise.all können mehrere Promises parallel ausgeführt werden. Die Methode wartet, bis alle Promises erfüllt sind, oder gibt einen Fehler zurück, wenn eines fehlschlägt.

Beispiel:

const promise1 = new Promise((resolve) => setTimeout(() => resolve('Ergebnis 1'), 1000));
const promise2 = new Promise((resolve) => setTimeout(() => resolve('Ergebnis 2'), 2000));

Promise.all([promise1, promise2])
  .then((results) => {
    console.log(results); // ['Ergebnis 1', 'Ergebnis 2']
  })
  .catch((error) => {
    console.error('Fehler:', error);
  });

Fehlerbehandlung

Die Fehlerbehandlung ist mit Promises deutlich verbessert. Du kannst catch verwenden, um Fehler abzufangen, und diese Behandlung kann über mehrere verkettete then-Aufrufe hinweg erfolgen.

Beispiel:

fetchData()
  .then((data) => {
    console.log('Daten erhalten:', data);
    return processData(data);
  })
  .then((processedData) => {
    console.log('Verarbeitete Daten:', processedData);
  })
  .catch((error) => {
    console.error('Es ist ein Fehler aufgetreten:', error);
  });

Wenn in irgendeinem der vorherigen Schritte ein Fehler auftritt, wird der catch-Block ausgeführt.

Promise-Methoden

Zusätzlich zu Promise.all gibt es weitere nützliche Methoden:

Beispiel mit Promise.race:

const promise1 = new Promise((resolve) => setTimeout(() => resolve('Schnell'), 500));
const promise2 = new Promise((resolve) => setTimeout(() => resolve('Langsam'), 1000));

Promise.race([promise1, promise2])
  .then((result) => {
    console.log(result); // 'Schnell'
  });

Fazit

Promises haben die Art und Weise revolutioniert, wie wir asynchronen Code in JavaScript schreiben. Sie bieten eine klare und strukturierte Methode zur Handhabung von asynchronen Operationen, erleichtern die Fehlerbehandlung und verbessern die Lesbarkeit des Codes. Durch das Verständnis und die effektive Nutzung von Promises kannst du robustere und wartbarere Anwendungen entwickeln.

Beginne noch heute, Promises in deinem Code zu verwenden, und erlebe den Unterschied in der Qualität und Wartbarkeit deines Codes!


Previous Post
Türchen 06
Next Post
Türchen 04