From d301724f4e9d71889dfdde9e36858755ec5f5e56 Mon Sep 17 00:00:00 2001 From: Denis Ergin Date: Sun, 5 Jan 2025 12:31:58 +0100 Subject: [PATCH] feat(slides): Promises + Async --- public/images/promise-allSettled.png | Bin 0 -> 14952 bytes .../slides/javascript/07-async/async.astro | 84 +++++ .../javascript/07-async/callbacks.astro | 69 ++++ .../javascript/07-async/eventloop.astro | 74 ++++ .../slides/javascript/07-async/helper.astro | 97 ++++++ .../slides/javascript/07-async/index.astro | 19 ++ .../javascript/07-async/introduction.astro | 32 ++ .../slides/javascript/07-async/promises.astro | 315 ++++++++++++++++++ .../slides/javascript/07-async/title.astro | 3 + src/pages/slides/javascript/07-async.astro | 8 + 10 files changed, 701 insertions(+) create mode 100644 public/images/promise-allSettled.png create mode 100644 src/components/slides/javascript/07-async/async.astro create mode 100644 src/components/slides/javascript/07-async/callbacks.astro create mode 100644 src/components/slides/javascript/07-async/eventloop.astro create mode 100644 src/components/slides/javascript/07-async/helper.astro create mode 100644 src/components/slides/javascript/07-async/index.astro create mode 100644 src/components/slides/javascript/07-async/introduction.astro create mode 100644 src/components/slides/javascript/07-async/promises.astro create mode 100644 src/components/slides/javascript/07-async/title.astro create mode 100644 src/pages/slides/javascript/07-async.astro diff --git a/public/images/promise-allSettled.png b/public/images/promise-allSettled.png new file mode 100644 index 0000000000000000000000000000000000000000..d576204b19a36ce24d410c67d69bc1df11847719 GIT binary patch literal 14952 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 K3s&;$`u`tP0GP4> literal 0 HcmV?d00001 diff --git a/src/components/slides/javascript/07-async/async.astro b/src/components/slides/javascript/07-async/async.astro new file mode 100644 index 0000000..51f9469 --- /dev/null +++ b/src/components/slides/javascript/07-async/async.astro @@ -0,0 +1,84 @@ +
+
+

Async & await

+
+ +
+

Async und Await sind 2 Mechanismen, die auf den vorgestellten Promises aufbauen und diese so erweitern, dass die Nutzung "einfacher" und "sauberer" für den Entwickler ist.

+

Im Allgemeinen sind diese Dinge einfach nur syntactic sugar für Promises.

+
+ +
+

async

+
+ +
+

Das keyword async kann vor Funktionen angestellt werden.

+

Die Nutzung des async-keywords erzeugt in JavaScript eine AsyncFunction, die wiederum ein Promise beim aufruf der Funktion erzeugt.

+
+ +
+

Der Beweis das async-functions nur eine Art "Wrapper" für Promises sind

+

+      async function test () {
+        return 52;
+      }
+  
+      test().then((response) => {
+        console.log(response);
+      });
+    
+
+ +
+

await

+
+ +
+

await ist das passende Gegenstück zum async keyword.

+

Wenn an einer async-function aufgerufenen Funktionen vorgestellt, wartet der Browser mit der Ausführung des restlichen Code bis der Promise ausgeführt worden ist.

+

Sollte die AsyncFunction einen Error werfen, so muss die Expression in einem try-catch-Block gewrapped sein um den Fehler abzufangen.

+

Wir können das Ergebnis des awaits einfach in einer Variable speichern (Erfolgsfall)

+
+ +
+

+      const into = document.getElementById('clipboard-result');
+
+      document.getElementById('clipboard-paste')
+      .onclick = async function () {
+        try {
+          const clipboardText = await navigator
+            .clipboard.readText();
+          into.innerText = `Kopierter Text:\n${clipboardText}`;
+        }
+        catch (err) {
+          into
+            .innerText = `Fehler beim lesen des Clipboards: ${err}`;
+        }
+      }
+    
+ + + +
+ + +
+ +
+

Wenn mit Promises gearbeitet wird, sollte man im besten Fall die Async-Await Syntax verwendet werden.

+

Sie ist sauberer und schneller zu schreiben und man verhindert Callback-Hells.

+
+
\ No newline at end of file diff --git a/src/components/slides/javascript/07-async/callbacks.astro b/src/components/slides/javascript/07-async/callbacks.astro new file mode 100644 index 0000000..42a8657 --- /dev/null +++ b/src/components/slides/javascript/07-async/callbacks.astro @@ -0,0 +1,69 @@ +
+
+

Callbacks

+
+ +
+

Callbacks sind ein simples Konzept. Im Grunde sind es Funktionen, die weitergegeben und später aufgerufen werden um wiederum Aktionen auszuführen.

+
+ +
+

+      const calculateAndCallback = (callback) => {
+        const result = 1 + 1;
+        callback();
+      }
+
+      const main = () => {
+        const myCallback = () => {
+          console.log('Callback wurde aufgerufen!');
+        };
+
+        console.log('main start');
+
+        calculateAndCallback(myCallback);
+
+        console.log('main end');
+      }
+
+      main();
+    
+
+ +
+

Meistens erwarten wir im Callback ein Ergebnis der aufgerufenen Funktion

+
+ +
+

+      const calculateAndCallback = (callback) => {
+        const result = 1 + 1;
+        callback(result);
+      }
+
+      const main = () => {
+        const myCallback = (result) => {
+          console.log(`Das Ergebnis ist: ${result}`);
+        };
+
+        calculateAndCallback(myCallback);
+      }
+
+      main();
+    
+
+ +
+

Wir notieren:

+

Callbacks sind Funktionen die von anderen Funktionen als Parameter entgegen genommen werden und zu einem bestimmten Zeitpunkt aufrufen.

+
+ +
+

Viele Funktionen die lang laufende "tasks" haben, erwarten 2 Callbacks: Einen für den Erfolgsfall, einer für den Fall des Scheiterns der Berechnung.

+
+ +
+

Vermeiden Sie geschachtelte Callbacks die Callbacks aus Callbacks aus Callbacks aufrufen. Sie machen den Code schlechter Wartbar und nicht mehr lesbar.

+

Umgangssprachlich hat sich hier der Begriff "Callback-Hell" heraus entwickelt.

+
+
\ No newline at end of file diff --git a/src/components/slides/javascript/07-async/eventloop.astro b/src/components/slides/javascript/07-async/eventloop.astro new file mode 100644 index 0000000..6f44457 --- /dev/null +++ b/src/components/slides/javascript/07-async/eventloop.astro @@ -0,0 +1,74 @@ +
+
+

Event-Loop

+
+ +
+

Bevor wir in die Thematik von Promises eintauchen können, müssen wir verstehen, wie JavaScript im inneren Funktioniert.

+

Im Allgemeinen läuft alles in einer Event-Loop. Diese Loop ist eine Warteschlange die bei jedem "Durchgang" eine Funktion aus besagter Warteschlange aufruft.

+

Funktionen werden durch verschiedene Mechanismen in die Warteschlange der Event-Loop gesteckt. Eine solche Methode haben wir bereits kennen gelernt: Events

+
+ +
+

Klickt der Nutzer auf einen Button, der einen JavaScript-EventListener hat, so wird die Funktion beim klicken in die Event-Loop eingereiht, um nächstmöglich ausgeführt zu werden.

+
+ +
+

Die Event-Loop führt also Funktionen aus, sammelt und prozessiert Events und führt eingereihte Unter-Aufgaben aus.

+

Hierfür verwendet die Event-Loop - stark vereinfacht - 3 Konzepte:

+
    +
  • Stack mit Frames
  • +
  • Queue mit Messages
  • +
  • Heap mit Objekten
  • +
+
+ +
+
    +
  1. "Events" (Messages) werden in die Queue gelegt
  2. +
  3. "Frames" (Funktionen) liegen im Stack
  4. +
  5. Objekte mit denen gearbeitet wird, sind im Heap.
  6. +
+
+ +
+

In JavaScript ist es nicht möglich die Abarbeitung einer Funktion anzuhalten.

+

Im Event Loop wird darauf gewartet, dass eine Funktion komplett abschließt / abgearbeitet wird bevor die nächste Message aus der Queue geladen wird.

+

Halten wir in einer Funktion die weitere Abarbeitung auf, so Sorgen wir gleichzeitig dafür dass der Browser in dieser Zeit nicht weiter arbeiten kann.

+

Wir empfinden dass als Lag oder simples "Nicht-Antworten" der Website auf Nutzer-Interaktionen (wenn die Abarbeitung länger als ein paar Millisekunden benötigt)

+
+ +
+

Es gibt ein paar Möglichkeiten als Entwickler Funktionen in die Queue zu legen anstatt Funktionen direkt auszuführen.

+

Diese Möglichkeiten sind in den Funktionen setInterval und setTimeout "versteckt".

+

"Versteckt" daher, weil sie eigentlich nicht direkt für diesen Gedacht sind.

+
+ +
+

setTimeout

+

setTimeout ist eine Funktion, die als Paramter einen Callback und eine Dauer in Millisekunden erwartet.

+

Nach der Angegebenen Zeit in Millisekunden wird der Callback in die Queue gesteckt um dort zum nächstmöglichen Zeitpunkt ausgeführt zu werden.

+
+ +
+

+      const toBeExecutedLater = () => {
+        console.log('Ich komme später!');
+      };
+
+      setTimeout(toBeExecutedLater, 500);
+
+      console.log('Ich komme vorher!');
+    
+
+ +
+

setInterval

+

setInterval ist sehr ähnlich zu setTimeout, ruft aber den angegebenen Callback in Intervallen der angegebenen Zeit in Millisekunden aus.

+
+ +
+

Beide Funktionen haben einen Rückgabewert, der eine Art ID repräsentiert.

+

Mithilfe dieser ID kann ein timeout bzw interval auch wieder angehalten werden, indem die ID in clearTimeout beziehungsweise in clearInterval heineingegeben wird.

+
+
\ No newline at end of file diff --git a/src/components/slides/javascript/07-async/helper.astro b/src/components/slides/javascript/07-async/helper.astro new file mode 100644 index 0000000..7b24482 --- /dev/null +++ b/src/components/slides/javascript/07-async/helper.astro @@ -0,0 +1,97 @@ +
+
+

Promise-Hilfsfunktionen

+
+ +
+

Das globale Promise-Objekt enthält eine Reihe an Funktionen die mit dem arbeiten mit Promises unterstützen kann.

+

Die Nachfolgend vorgestellten Funktionen nehmen immer ein Array aus Promises entgegen. Die Resultate aus diesen Funktionen variieren.

+
+ +
+

Promise.all()

+
+ +
+

Promise.all([ /* Promises */ ]) wartet auf die Erfolgreiche Abarbeitung aller im Array befindlichen Promises.

+

Die Ergebnisse aller Promises werden im Resultat (.then() oder await) in einem Array In der gleichen Reihenfolge wie im Übergabe-Array gepackt.

+
+ +
+

+      const promise1 = new Promise((resolve) => resolve(42));
+      const promise2 = new Promise((resolve) => resolve(43));
+      const promise3 = new Promise((resolve) => resolve(44));
+
+      const results = await Promise
+        .all([promise1, promise2, promise3]);
+
+      // [42, 43, 44]
+      console.log(results);
+    
+
+ +
+

Wirft einer der Promises einen Error, so wirft auch das .all einen Fehler

+
+ +
+

+      const promise1 = new Promise((resolve) => resolve(42));
+      const promise2 = new Promise((_, reject) => reject(43));
+      const promise3 = new Promise((resolve) => resolve(44));
+
+      // Uncaught (in promise) 43
+      const results = await Promise
+        .all([promise1, promise2, promise3]);
+    
+
+ +
+

Promise.allSettled()

+
+ +
+

Ähnlich zu .all, bei einem Error wird die Ausführung des restlichen Codes aber normal ausgeführt:

+

+      const promise1 = new Promise((resolve) => resolve(42));
+      const promise2 = new Promise((_, reject) => reject(43));
+      const promise3 = new Promise((resolve) => resolve(44));
+
+      const results = await Promise
+        .allSettled([promise1, promise2, promise3]);
+
+      console.log(results);
+    
+ 3 Promises werden erstellt, das zweite wird rejected. Alle Promises werden in einem Array an Promises.allSettled übergeben und awaited. Das Resultat sind 3 Werte in einem Array, das 2. Element ist rejected mit einer reason. +
+ +
+

Promise.any()

+
+ +
+

.any() gibt das erste, erfolgreiche Promise zurück (inklusive des Ergebnisses).

+

Sollten alle Promises rejected werden, so rejected die Funktion selber mit einem Array an reasons.

+
+ +
+

+      const promise1 = new Promise((_, reject) => reject(42));
+      const promise2 = new Promise((_, reject) => reject(43));
+      const promise3 = new Promise((resolve) => resolve(44));
+
+      const results = await Promise
+        .any([promise1, promise2, promise3]);
+
+      // 44
+      console.log(results);
+    
+
+ +
+

Neben diesen Aggregatoren-Funktionen gibt es noch 2 Hilfsfunktionen:

+

Promise.resolve("Wert") gibt ein sofort "fullfiltes" Promise zurück, wir können auf den Rückgabewert wie bisher auch mittels await oder .then() zugreifen.

+

Promise.reject("Grund") ist ähnlich zu .resolve(), rejected aber das Promise mit einem angegebenen Grund.

+
+
\ No newline at end of file diff --git a/src/components/slides/javascript/07-async/index.astro b/src/components/slides/javascript/07-async/index.astro new file mode 100644 index 0000000..e03cc20 --- /dev/null +++ b/src/components/slides/javascript/07-async/index.astro @@ -0,0 +1,19 @@ +--- +import Title from "./title.astro"; +import Introduction from "./introduction.astro"; +import Promises from "./promises.astro"; +import Callbacks from "./callbacks.astro"; +import Async from "./async.astro"; +import EventLoop from "./eventloop.astro"; +import Helper from "./helper.astro"; +--- + +
+ + <Introduction /> + <Callbacks /> + <EventLoop /> + <Promises /> + <Async /> + <Helper /> +</div> \ No newline at end of file diff --git a/src/components/slides/javascript/07-async/introduction.astro b/src/components/slides/javascript/07-async/introduction.astro new file mode 100644 index 0000000..f209d1b --- /dev/null +++ b/src/components/slides/javascript/07-async/introduction.astro @@ -0,0 +1,32 @@ +<section> + <section> + <h2>Asynchroner Code - Eine Einführung</h2> + </section> + + <section> + <p>JavaScript ist eine "Single Threaded" Script-Sprache. Im Allgemeinen heißt dies:</p> + <p>JavaScript wird nur an einer Stelle zu jedem Zeitpunkt ausgeführt. Das macht es uns möglich JavaScript einfach zu halten da wir keine Race-Conditions "bauen" können.</p> + <p>Lang laufende Berechnungen sorgen dafür, dass keine anderen Aktionen in der Zwischenzeit ausgeführt werden können. User nehmen dies als "nicht-reagieren" einer Webanwendung war.</p> + </section> + + <section> + <p>Als Web-Developer ist es daher besonders wichtig, so wenig <strong>lang-laufende Operationen</strong> wie möglich zu erzeugen.</p> + <p>Leider ist es aber so, dass wir als Entwickler nicht immer in die Dauer bestimmter Aktionen eingreifen können.</p> + </section> + + <section> + <p>Im Allgemeinen sind "Input-Output" Aktivitäten jeder Art eine der am längsten dauernden Operationen.</p> + <p>Beispiele solcher Aktivitäten sind z.B.: Datei-Operationen (lesend, schreibend), Netzwerk-Requests, Kommunikation mit anderen Systemen (Bluetooth)</p> + <p>Aber: Hier haben wir einen Entscheidenden Vorteil. All diese Dinge sind über eine API in einer kompilierten Sprachen (meistens C oder C++) geschrieben.</p> + <p>Sie sind also soweit "weg abstrahiert", dass wir uns nicht darum Sorgen müssen dass ein Funktionsaufruf länger dauert. JavaScript führt solche Aktionen im Hintergrund aus. Wir müssen nur noch das Ergebnis interpretieren.</p> + </section> + + <section> + <p>Dafür (also für unter Umständen lang laufenden Operationen) gibt es einen Abstraktions-Layer der uns das arbeiten deutlich vereinfacht: Promises.</p> + <p>Ein Promise ist genau das: Ein <strong>Versprechen</strong> dass eine Funktion <strong>irgendwann in der Zukunft</strong> abschließt und einen Wert liefert.</p> + </section> + + <section> + <p>Bevor wir aber direkt damit loslegen, müssen wir zuvor noch ein anderes Konzept in JavaScript lernen und verstehen.</p> + </section> +</section> \ No newline at end of file diff --git a/src/components/slides/javascript/07-async/promises.astro b/src/components/slides/javascript/07-async/promises.astro new file mode 100644 index 0000000..bed4f25 --- /dev/null +++ b/src/components/slides/javascript/07-async/promises.astro @@ -0,0 +1,315 @@ +<section> + <section> + <h2>Promises</h2> + </section> + + <section> + <p>Wie bereits zuvor erwähnt sind Promises ein <strong>Versprechen, dass etwas in er Zukunft fertig sein wird (Funktion)</strong>.</p> + <p>In heutzutage modernen Browsern ist jede lang-laufende Operation hinter einem solchen Promise versteckt.</p> + <p>Promises sorgen dafür das eine Funktion (Message) in die Queue gesteckt wird und das der Event-Loop diese später ausführt.</p> + </section> + + <section> + <p>Ein Promise zu erstellen ist relativ simpel</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + const myPromise = new Promise(); + </code></pre> + </section> + + <section> + <p>Dieses Promise macht nun aber nicht viel. Ein Promise benötigt eine Funktion die im Hintergrund ausgeführt wird.</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + const myPromise = new Promise(() => { + console.log('Hallo Welt!'); + }); + </code></pre> + <p>Wir sollten beim ausführen dann ein "Hallo Welt!" in den Developer Tools sehen</p> + </section> + + <section> + <p>Wie sieht das nun aber alles aus wenn wir schauen wollen in welcher Reihenfolge das alles ausgeführt wird?</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + const myPromise = new Promise(() => { + console.log('Hallo Welt!'); + }); + + console.log('Komme ich davor oder danach?'); + </code></pre> + </section> + + <section> + <p>Ein Promise macht auch nicht mehr als den Callback auszuführen und auf ein Resultat zu warten.</p> + <p>Wenn es nichts gibt auf das man warten muss, ist ein Promise auch sofort abgeschlossen.</p> + </section> + + <section> + <p>Bevor wir weiter machen, gehen wir auf den Callback des Promises näher ein.</p> + <p>Dieser Callback erhält nämlich 2 Parameter, die wiederrum Callbacks sind</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + const p = new Promise((resolve, reject) => { + // ??? + }); + </code></pre> + </section> + + <section> + <p>Oft werden diese 2 Callbacks als <code>resolve</code> und <code>reject</code> definiert.</p> + <p>Schauen wir mal, was die Variable als Inhalt hat, in der wir dieses Promise packt:</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + const myPromise = new Promise(() => { + console.log('Hallo Welt!'); + }); + + // Promise { <state>: "pending" } + console.log(myPromise); + </code></pre> + </section> + + <section> + <p>Das Promise hat einen Zustand der in "pending" hängt.</p> + <p>Dieser Zustand wird sich in dieser Form so auch nicht mehr ändern.</p> + <p>Hierfür sind die Callback-Funktionen <code>resolve & reject</code> gedacht.</p> + </section> + + <section> + <p>Rufen wir mal die Funktion <code>resolve</code> innerhalb des Promises auf</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + const myPromise = new Promise((resolve) => { + console.log('Hallo Welt!'); + resolve(); + }); + + // Promise { <state>: "fulfilled", <value>: undefined } + console.log(myPromise); + </code></pre> + </section> + + <section> + <p>Die Promise ist nun <strong>fulfilled</strong> und scheint einen <code>value</code> zu beinhalten, der in diesem Fall <code>undefined</code> ist.</p> + </section> + + <section> + <p>Sehen wir uns noch kurz an, wenn der Promise <strong>rejected</strong> wird</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + const myPromise = new Promise((_, reject) => { + console.log('Hallo Welt!'); + reject(); + }); + + // Promise { <state>: "rejected", <value>: undefined } + console.log(myPromise); + </code></pre> + </section> + + <section> + <p>Gut, wir wissen nun dass der Promise "rejected" wurde, aber was heißt das genau?</p> + <p>Nun, Promises funktionieren ein wenig anders als einfach aufgerufene Funktionen.</p> + <p>Wenn wir die Variable <code>myPromise</code> untersuchen, sehen wir keine Möglichkeit, auf den Zustand oder den Wert zuzugreifen.</p> + <p>Aber es gibt ein paar Funktionen: <code>then, catch & finally</code>.</p> + </section> + + <section> + <p>Wir können nur auf Resultate und den Allgemeinen Ausgang eines Promise reagieren indem wir mit diesen Funktionen arbeiten.</p> + <p>Diese Funktionen sind <code>chainable</code>. Wir können mehrere <code>.then & .catch</code> nacheinander aufrufen.</p> + <p>Wenn ein Promise erfolgreich ist und <code>resolve</code> aufruft, wird die Funktion in <code is:raw>.then(() => {})</code> aufgerufen</p> + </section> + + <section> + <p>Sollte das Promise nicht erfolgreich gewesen sein und hat <code>reject()</code> aufgerufen, so wird <code is:raw>.catch(() => {})</code> aufgerufen.</p> + <p>Wir können nicht aus einem Promise "ausbrechen". Wir können aber Resultate aus einem Promise zu jederzeit in den äußeren Scope verschieben und weitere Funktionen aufrufen.</p> + </section> + + <section> + <p>Sehen wir uns das ganze nun in Aktion an:</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + const myPromise = new Promise((resolve, reject) => { + resolve(); + }); + + myPromise.then(() => { + console.log('Das war erfolgreich!'); + }); + </code></pre> + </section> + + <section> + <p>Der Fehlerfall ist auch leicht:</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + const myPromise = new Promise((resolve, reject) => { + reject(); + }); + + myPromise.catch(() => { + console.log('Das war diesmal NICHT erfolgreich!'); + }); + </code></pre> + </section> + + <section> + <p>Führen wir beide Varianten einmal zusammen:</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + const myPromise = new Promise((resolve, reject) => { + reject(); + }); + + myPromise + .then(() => { + console.log('Das ging mal gut!'); + }) + .catch(() => { + // Durch das reject landen wir nur hier! + console.log('Das war diesmal NICHT erfolgreich!'); + }); + </code></pre> + </section> + + <section> + <p>Das <code>catch</code> muss aber nicht das Ende sein, wenn wir nach dem <code>catch</code> noch etwas ausführen wollen, können wir einfach mit <code>.then</code> weiter machen.</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + const myPromise = new Promise((resolve, reject) => { + reject(); + }); + + myPromise + .then(() => { + console.log('Das ging mal gut!'); + }) + .catch(() => { + console.log('Das war diesmal NICHT erfolgreich!'); + }) + .then(() => { + console.log('Es gibt mehr danach!'); + }); + </code></pre> + </section> + + <section> + <p>Das weitere <code>.then</code> und <code>.catch</code> aufgerufen werden können, hat einen entscheidenden Vorteil:</p> + <p>Wir können in <code>.then</code> und <code>.catch</code> einen Fehler werfen um ein anderes <code>.catch auszulösen.</code></p> + <p>Gleichzeitig bedeutet ein nicht vorhanden sein eines Errors, dass das nächste <code>.then</code> aufgerufen wird.</p> + </section> + + <section> + <pre class="js"><code data-trim data-line-numbers is:raw> + const myPromise = new Promise((resolve, reject) => { + resolve(); + }); + + myPromise + .then(() => { + console.log('Das ging mal gut!'); + throw new Error('Pech gehabt!'); + }) + .catch(() => { + console.log('Das war diesmal NICHT erfolgreich!'); + }) + .then(() => { + console.log('Es gibt mehr danach!'); + }); + </code></pre> + </section> + + <section> + <p>Um am Ende auf jeden Fall eine Funktion auszuführen gibt es zu guter letzt noch die Funktion <code>.finally</code>.</p> + <p>Der Aufruf sorgt dafür, dass in jedem Fall - egal ob ein Fehler geworfen wurde oder nicht - Code ausgeführt wird.</p> + </section> + + <section> + <pre class="js"><code data-trim data-line-numbers is:raw> + const myPromise = new Promise((resolve, reject) => { + resolve(); + }); + + myPromise + .then(() => { + console.log('Das ging mal gut!'); + }) + .catch(() => { + console.log('Das war diesmal NICHT erfolgreich!'); + }) + .finally(() => { + console.log('Ich geschehe immer!'); + }); + </code></pre> + </section> + + <section> + <p>Parameter in <code>.catch</code> und <code>.then</code></p> + <p>Wir erhalten in diesen beiden Funktionen Informationen.</p> + <p><code>.catch</code> erhält in der Regel den Error der davor geworfen wurde, oder aber was in die Funktion <code>reject</code> mitgegeben wurde.</p> + </section> + + <section> + <pre class="js"><code data-trim data-line-numbers is:raw> + const p = new Promise((_, reject) => { + reject('Zum Scheitern verdonnert'); + }); + + p.catch((reason) => { + console.log(reason); + throw new Error('Für immer'); + }) + .catch((err) => { + console.log(err); + }); + </code></pre> + </section> + + <section> + <p>Das gleiche Funktioniert auch mit <code>resolve()</code> und <code>.then()</code></p> + <pre class="js"><code data-trim data-line-numbers is:raw> + const p = new Promise((resolve) => { + resolve(42); + }); + + p.then((zahl) => { + console.log(zahl); + return "Die einzig wahre Zahl"; + }) + .then((x) => { + console.log(x); + }); + </code></pre> + </section> + + <section> + <p>Ein Konkretes Beispiel</p> + <p>Nachfolgend lesen wir den Inhalt aus dem System-Clipboard aus. Die Funktionalität, die uns der Browser dafür gibt, liefert einen Promise.</p> + </section> + + <section> + <pre class="js"><code data-trim data-line-numbers is:raw> + const into = document.getElementById('clipboard-result'); + document.getElementById('clipboard-paste').onclick = function () { + navigator.clipboard.readText() + .then((clipboardText) => { + into.innerText = `Kopierter Text:\n${clipboardText}`; + }) + .catch((err) => { + into.innerText = `Fehler beim lesen des Clipboards: ${err}`; + }); + } + </code></pre> + + <button id="clipboard-paste"> + Paste + </button> + + <div id="clipboard-result"> + Ergebnis... + </div> + + <script> + const into = document.getElementById('clipboard-result')!; + document.getElementById('clipboard-paste')!.onclick = function () { + navigator.clipboard.readText() + .then((clipboardText) => { + into.innerText = `Kopierter Text:\n${clipboardText}`; + }) + .catch((err) => { + into.innerText = `Fehler beim lesen des Clipboards: ${err}`; + }); + } + </script> + </section> +</section> \ No newline at end of file diff --git a/src/components/slides/javascript/07-async/title.astro b/src/components/slides/javascript/07-async/title.astro new file mode 100644 index 0000000..304dc18 --- /dev/null +++ b/src/components/slides/javascript/07-async/title.astro @@ -0,0 +1,3 @@ +<section> + <h1>JavaScript: Asynchroner Code</h1> +</section> \ No newline at end of file diff --git a/src/pages/slides/javascript/07-async.astro b/src/pages/slides/javascript/07-async.astro new file mode 100644 index 0000000..9c1e2e2 --- /dev/null +++ b/src/pages/slides/javascript/07-async.astro @@ -0,0 +1,8 @@ +--- +import Reveal from "../../../layouts/Reveal.astro"; +import Slides from "../../../components/slides/javascript/07-async/index.astro"; +--- + +<Reveal title="JavaScript: Asynchroner Code"> + <Slides /> +</Reveal> \ No newline at end of file