Kodokon kodokon.com

Asynchronität in der Praxis

Setze async/await in deinen Routen ein und behandle asynchrone Fehler, ohne den Server lahmzulegen.

10 Min. · 3 Fragen

Diese Lektion in Kodokon öffnen

Deine echten Routen geben keine Arrays aus dem Arbeitsspeicher zurück: Sie lesen Dateien, fragen eine Datenbank ab, rufen andere APIs auf. All diese Operationen sind asynchron. async/await kennst du seit dem JavaScript-Lernpfad; sehen wir uns an, wie du sie sauber in einem Server einsetzt. Erste gute Nachricht: Eine Routenfunktion darf async sein.

JAVASCRIPT
import express from "express";
import { readFile } from "node:fs/promises";

const app = express();

app.get("/report", async (req, res) => {
  const raw = await readFile("report.json", "utf8");
  res.json(JSON.parse(raw));
});

app.listen(3000);

Dieser Code funktioniert... solange report.json existiert. Schlägt das Lesen fehl, wird das Promise abgelehnt und je nach Express-Version bleibt die Anfrage ohne Antwort oder der Fehler sickert in die Logs. Die professionelle Regel: Jede async-Route behandelt ihre Fehler, mit try/catch und next(error).

JAVASCRIPT
app.get("/report", async (req, res, next) => {
  try {
    const raw = await readFile("report.json", "utf8");
    res.json(JSON.parse(raw));
  } catch (error) {
    next(error);
  }
});

next(error) übergibt den Fehler an den zentralen Fehler-Handler. Das ist eine Middleware mit vier Parametern, die nach allen Routen deklariert wird. Ein einziger Ort, um Fehler zu protokollieren und zu formatieren: Genau das unterscheidet eine wartbare API von einem Wochenendprojekt.

JAVASCRIPT
app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).json({
    error: "Internal server error"
  });
});
Immer zuletzt, nach den Routen

Ein letzter Reflex, den du dir aneignen solltest: Parallelität. Zwei unabhängige Operationen, die mit zwei await hintereinandergehängt werden, laufen nacheinander ab. Promise.all startet sie gemeinsam: Die Antwortzeit ist die der langsamsten, nicht die Summe beider.

JAVASCRIPT
async function fetchUsers() {
  return [{ id: 1, name: "Ada" }];
}

async function fetchTasks() {
  return [{ id: 1, title: "Review the code" }];
}

app.get("/dashboard", async (req, res, next) => {
  try {
    const [users, tasks] = await Promise.all([
      fetchUsers(),
      fetchTasks()
    ]);
    res.json({ users, tasks });
  } catch (error) {
    next(error);
  }
});

Wissenscheck

Stelle sicher, dass du die wichtigsten Punkte dieser Lektion behalten hast.

  1. Was machst du in einer async-Route mit einem Fehler, den catch abgefangen hat?
    • Ihn mit console.log protokollieren und weitermachen
    • next(error) aufrufen, um ihn an den Fehler-Handler zu übergeben
    • Die Anfrage automatisch wiederholen
  2. Zwei unabhängige asynchrone Aufrufe sollen so schnell wie möglich laufen. Welchen Ansatz wählst du?
    • Sie mit zwei aufeinanderfolgenden await verketten
    • Sie gemeinsam mit Promise.all starten
    • Zwischen beiden setTimeout verwenden
  3. Woran erkennt Express eine Middleware zur Fehlerbehandlung?
    • An ihrer Signatur mit vier Parametern, mit err an erster Stelle
    • Am Namen der Funktion, der errorHandler lauten muss
    • An ihrer Position am Anfang der Datei