Synchrone und asynchrone Programmierung

Geschätzte Lektüre: 7 Minuten 393 Ansichten

JavaScript ist eine single-threaded Sprache, aber sie kann sowohl synchron als auch asynchron arbeiten.

Synchrone Programmierung

Bei synchroner Programmierung werden Anweisungen nacheinander ausgeführt. Jede Operation blockiert die Ausführung, bis sie abgeschlossen ist.

Eigenschaften synchroner Programmierung:

  • Blockierend: Jede Operation muss abgeschlossen sein, bevor die nächste beginnt
  • Einfach zu verstehen und nachzuvollziehen
  • Kann zu Performance-Problemen führen, wenn Operationen lange dauern

Beispiel für synchrone Ausführung:

console.log("Erster Schritt"); // Wird zuerst ausgeführt

function syncFunction() {
    console.log("Zweiter Schritt - innerhalb der Funktion");
}

syncFunction(); // Wird als nächstes ausgeführt

console.log("Dritter Schritt"); // Wird zuletzt ausgeführt

Ausgabe:

Erster Schritt
Zweiter Schritt - innerhalb der Funktion
Dritter Schritt

Problem mit synchronem Code:

console.log("Start");

// Eine blockierende Operation (z.B. eine große Schleife)
for (let i = 0; i < 1000000000; i++) {
    // Diese Schleife blockiert die Ausführung
}

console.log("Ende"); // Wird erst nach der Schleife ausgegeben

Asynchrone Programmierung

Asynchrone Programmierung ermöglicht es, dass Operationen im Hintergrund ausgeführt werden, ohne den Haupt-Thread zu blockieren. Wenn die Operation abgeschlossen ist, wird eine Callback-Funktion aufgerufen.

Eigenschaften asynchroner Programmierung:

  • Nicht-blockierend: Der Code läuft weiter, während Operationen im Hintergrund laufen
  • Komplexer zu verstehen und zu debuggen
  • Besser für I/O-Operationen, Netzwerkanfragen, etc.

Beispiele für asynchrone Programmierung:
setTimeout – einfaches asynchrones Beispiel

console.log("Start");

setTimeout(() => {
    console.log("Asynchroner Code");
}, 2000);

console.log("Ende");

Ausgabe:

Start
Ende
Asynchroner Code (nach 2 Sekunden)

• Asynchrone Dateioperationen mit Node.js

const fs = require('fs');

console.log("Datei wird gelesen...");

fs.readFile('beispiel.txt', 'utf8', (err, data) => {
    if (err) throw err;
    console.log("Dateiinhalt:", data);
});

console.log("Diese Nachricht erscheint, während die Datei noch gelesen wird");

• Netzwerkanfragen mit fetch

console.log("Start der Anfrage");

fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => {
        console.log("Daten empfangen:", data);
    })
    .catch(error => {
        console.error("Fehler:", error);
    });

console.log("Ende des Skripts (aber die Anfrage läuft noch)");

Wie funktioniert asynchrone Programmierung in JavaScript?

JavaScript verwendet das Event-Loop-Modell für asynchrone Operationen:

  • Call Stack: Führt synchronen Code aus
  • Web APIs: Browser-APIs (oder Node.js APIs) die asynchrone Operationen handhaben
  • Callback Queue: Speichert Callbacks von abgeschlossenen asynchronen Operationen
  • Event Loop: Überwacht den Call Stack und fügt Callbacks aus der Queue hinzu, wenn der Stack leer ist

Methoden für asynchrone Programmierung

• Callbacks

function getData(callback) {
    setTimeout(() => {
        callback({ name: "Max", age: 30 });
    }, 1000);
}

getData(data => {
    console.log(data); // { name: "Max", age: 30 }
});

Problem: „Callback Hell“ bei verschachtelten Aufrufen

• Promises

function getData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve({ name: "Max", age: 30 });
            // oder reject(new Error("Fehler aufgetreten"));
        }, 1000);
    });
}

getData()
    .then(data => console.log(data))
    .catch(error => console.error(error));

• Async/Await (syntaktischer Zucker für Promises)

async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error("Fehler:", error);
    }
}

fetchData();

Vergleich: Synchron vs. Asynchron

AspektSynchronAsynchron
AusführungsreihenfolgeStreng sequenziellNicht-blockierend, unvorhersehbare Reihenfolge
BlockierungBlockiert den Haupt-ThreadBlockiert nicht den Haupt-Thread
VerwendungEinfache OperationenI/O, Netzwerk, Timer
FehlerbehandlungTry-catchCallbacks, Promises, async/await
LesbarkeitLinear und einfachKomplexer (Callback Hell)

Praxisbeispiel: Synchron vs. Asynchron

• Synchroner Ansatz (problematisch im Browser):

function syncDelay(ms) {
    const start = Date.now();
    while (Date.now() - start < ms) {}
    console.log("Verzögerung beendet");
}

console.log("Start");
syncDelay(3000); // Blockiert den Browser für 3 Sekunden
console.log("Ende");

• Asynchroner Ansatz (besser):

function asyncDelay(ms) {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log("Verzögerung beendet");
            resolve();
        }, ms);
    });
}

console.log("Start");
asyncDelay(3000).then(() => {
    console.log("Ende");
});

// Oder mit async/await:
async function run() {
    console.log("Start");
    await asyncDelay(3000);
    console.log("Ende");
}
run();

Wann was verwenden?

  • Synchron: Für einfache, schnelle Operationen die nicht blockieren sollen
  • Asynchron: Für I/O-Operationen, Netzwerkanfragen, Timer oder rechenintensive Tasks (mit Web Workers)

JavaScripts asynchrone Natur ist einer der Gründe für seine Popularität, da es effiziente nicht-blockierende I/O-Operationen ermöglicht, besonders in Node.js.

Dieses Dokument teilen

Synchrone und asynchrone Programmierung

Oder Link kopieren

INHALT

Abonnieren

×
Cancel