1
0
Fork 0
mirror of https://github.com/TheTaz25/denis.ergin.git synced 2025-07-06 11:38:49 +00:00

feat(slides): Promises + Async

This commit is contained in:
Denis Ergin 2025-01-05 12:31:58 +01:00
parent 5786a669e5
commit d301724f4e
10 changed files with 701 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -0,0 +1,84 @@
<section>
<section>
<h2>Async &amp; await</h2>
</section>
<section>
<p>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.</p>
<p>Im Allgemeinen sind diese Dinge einfach nur <strong>syntactic sugar</strong> für Promises.</p>
</section>
<section>
<h3>async</h3>
</section>
<section>
<p>Das keyword <code>async</code> kann vor Funktionen angestellt werden.</p>
<p>Die Nutzung des async-keywords erzeugt in JavaScript eine <code>AsyncFunction</code>, die wiederum ein Promise beim aufruf der Funktion erzeugt.</p>
</section>
<section>
<p>Der Beweis das async-functions nur eine Art "Wrapper" für Promises sind</p>
<pre class="js"><code data-trim data-line-numbers is:raw>
async function test () {
return 52;
}
test().then((response) => {
console.log(response);
});
</code></pre>
</section>
<section>
<h3>await</h3>
</section>
<section>
<p><code>await</code> ist das passende Gegenstück zum <code>async</code> keyword.</p>
<p>Wenn an einer async-function aufgerufenen Funktionen vorgestellt, wartet der Browser mit der Ausführung des restlichen Code bis der Promise <strong>ausgeführt</strong> worden ist.</p>
<p>Sollte die AsyncFunction einen Error werfen, so muss die Expression in einem try-catch-Block gewrapped sein um den Fehler abzufangen.</p>
<p>Wir können das Ergebnis des awaits einfach in einer Variable speichern (Erfolgsfall)</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 = 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}`;
}
}
</code></pre>
<button id="clipboard-paste2">Paste</button>
<div id="clipboard-result2"></div>
<script>
const into = document.getElementById('clipboard-result2')!;
document.getElementById('clipboard-paste2')!.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}`;
}
}
</script>
</section>
<section>
<p>Wenn mit Promises gearbeitet wird, sollte man im besten Fall die Async-Await Syntax verwendet werden.</p>
<p>Sie ist sauberer und schneller zu schreiben und man verhindert <strong>Callback-Hells</strong>.</p>
</section>
</section>

View file

@ -0,0 +1,69 @@
<section>
<section>
<h2>Callbacks</h2>
</section>
<section>
<p>Callbacks sind ein simples Konzept. Im Grunde sind es Funktionen, die weitergegeben und später aufgerufen werden um wiederum Aktionen auszuführen.</p>
</section>
<section>
<pre class="js"><code data-trim data-line-numbers is:raw style="max-height: 580px;">
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();
</code></pre>
</section>
<section>
<p>Meistens erwarten wir im Callback ein Ergebnis der aufgerufenen Funktion</p>
</section>
<section>
<pre class="js"><code data-trim data-line-numbers is:raw style="max-height: 580px;">
const calculateAndCallback = (callback) => {
const result = 1 + 1;
callback(result);
}
const main = () => {
const myCallback = (result) => {
console.log(`Das Ergebnis ist: ${result}`);
};
calculateAndCallback(myCallback);
}
main();
</code></pre>
</section>
<section>
<p>Wir notieren:</p>
<p>Callbacks sind Funktionen die von anderen Funktionen als Parameter entgegen genommen werden und zu einem bestimmten Zeitpunkt aufrufen.</p>
</section>
<section>
<p>Viele Funktionen die lang laufende "tasks" haben, erwarten 2 Callbacks: Einen für den Erfolgsfall, einer für den Fall des Scheiterns der Berechnung.</p>
</section>
<section>
<p>Vermeiden Sie geschachtelte Callbacks die Callbacks aus Callbacks aus Callbacks aufrufen. Sie machen den Code schlechter Wartbar und nicht mehr lesbar.</p>
<p>Umgangssprachlich hat sich hier der Begriff "Callback-Hell" heraus entwickelt.</p>
</section>
</section>

View file

@ -0,0 +1,74 @@
<section>
<section>
<h2>Event-Loop</h2>
</section>
<section>
<p>Bevor wir in die Thematik von Promises eintauchen können, müssen wir verstehen, wie JavaScript im inneren Funktioniert.</p>
<p>Im Allgemeinen läuft alles in einer Event-Loop. Diese Loop ist eine Warteschlange die bei jedem "Durchgang" eine Funktion aus besagter Warteschlange aufruft.</p>
<p>Funktionen werden durch verschiedene Mechanismen in die Warteschlange der Event-Loop gesteckt. Eine solche Methode haben wir bereits kennen gelernt: Events</p>
</section>
<section>
<p>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.</p>
</section>
<section>
<p>Die Event-Loop führt also Funktionen aus, sammelt und prozessiert Events und führt eingereihte Unter-Aufgaben aus.</p>
<p>Hierfür verwendet die Event-Loop - <strong>stark vereinfacht</strong> - 3 Konzepte:</p>
<ul>
<li>Stack mit Frames</li>
<li>Queue mit Messages</li>
<li>Heap mit Objekten</li>
</ul>
</section>
<section>
<ol>
<li>"Events" (Messages) werden in die Queue gelegt</li>
<li>"Frames" (Funktionen) liegen im Stack</li>
<li>Objekte mit denen gearbeitet wird, sind im Heap.</li>
</ol>
</section>
<section>
<p>In JavaScript ist es nicht möglich die Abarbeitung einer Funktion anzuhalten.</p>
<p>Im Event Loop wird darauf gewartet, dass eine Funktion komplett abschließt / abgearbeitet wird bevor die nächste Message aus der Queue geladen wird.</p>
<p>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.</p>
<p>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)</p>
</section>
<section>
<p>Es gibt ein paar Möglichkeiten als Entwickler Funktionen in die Queue zu legen anstatt Funktionen direkt auszuführen.</p>
<p>Diese Möglichkeiten sind in den Funktionen <code>setInterval</code> und <code>setTimeout</code> "versteckt".</p>
<p>"Versteckt" daher, weil sie eigentlich nicht direkt für diesen Gedacht sind.</p>
</section>
<section>
<h3>setTimeout</h3>
<p><code>setTimeout</code> ist eine Funktion, die als Paramter einen Callback und eine Dauer in Millisekunden erwartet.</p>
<p>Nach der Angegebenen Zeit in Millisekunden wird der Callback in die Queue gesteckt um dort zum nächstmöglichen Zeitpunkt ausgeführt zu werden.</p>
</section>
<section>
<pre class="js"><code data-trim data-line-numbers is:raw>
const toBeExecutedLater = () => {
console.log('Ich komme später!');
};
setTimeout(toBeExecutedLater, 500);
console.log('Ich komme vorher!');
</code></pre>
</section>
<section>
<h3>setInterval</h3>
<p><code>setInterval</code> ist sehr ähnlich zu <code>setTimeout</code>, ruft aber den angegebenen Callback in Intervallen der angegebenen Zeit in Millisekunden aus.</p>
</section>
<section>
<p>Beide Funktionen haben einen Rückgabewert, der eine Art ID repräsentiert.</p>
<p>Mithilfe dieser ID kann ein timeout bzw interval auch wieder angehalten werden, indem die ID in <code>clearTimeout</code> beziehungsweise in <code>clearInterval</code> heineingegeben wird.</p>
</section>
</section>

View file

@ -0,0 +1,97 @@
<section>
<section>
<h2>Promise-Hilfsfunktionen</h2>
</section>
<section>
<p>Das globale <code>Promise</code>-Objekt enthält eine Reihe an Funktionen die mit dem arbeiten mit Promises unterstützen kann.</p>
<p>Die Nachfolgend vorgestellten Funktionen nehmen immer ein Array aus Promises entgegen. Die Resultate aus diesen Funktionen variieren.</p>
</section>
<section>
<h3>Promise.all()</h3>
</section>
<section>
<p><code>Promise.all([ /* Promises */ ])</code> wartet auf die <strong>Erfolgreiche</strong> Abarbeitung aller im Array befindlichen Promises.</p>
<p>Die Ergebnisse aller Promises werden im Resultat (.then() oder await) in einem Array <strong>In der gleichen Reihenfolge</strong> wie im Übergabe-Array gepackt.</p>
</section>
<section>
<pre class="js"><code data-trim data-line-numbers is:raw>
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);
</code></pre>
</section>
<section>
<p>Wirft einer der Promises einen Error, so wirft auch das <code>.all</code> einen Fehler</p>
</section>
<section>
<pre class="js"><code data-trim data-line-numbers is:raw>
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]);
</code></pre>
</section>
<section>
<h3>Promise.allSettled()</h3>
</section>
<section>
<p>Ähnlich zu <code>.all</code>, bei einem Error wird die Ausführung des restlichen Codes aber normal ausgeführt:</p>
<pre class="js"><code data-trim data-line-numbers is:raw>
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);
</code></pre>
<img src="/images/promise-allSettled.png" width="550" alt="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.">
</section>
<section>
<h3>Promise.any()</h3>
</section>
<section>
<p><code>.any()</code> gibt das <strong>erste, erfolgreiche</strong> Promise zurück (inklusive des Ergebnisses).</p>
<p>Sollten alle Promises rejected werden, so rejected die Funktion selber mit einem Array an <code>reasons</code>.</p>
</section>
<section>
<pre class="js"><code data-trim data-line-numbers is:raw>
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);
</code></pre>
</section>
<section>
<p>Neben diesen Aggregatoren-Funktionen gibt es noch 2 Hilfsfunktionen:</p>
<p><code>Promise.resolve("Wert")</code> gibt ein sofort "fullfiltes" Promise zurück, wir können auf den Rückgabewert wie bisher auch mittels await oder .then() zugreifen.</p>
<p><code>Promise.reject("Grund")</code> ist ähnlich zu .resolve(), rejected aber das Promise mit einem angegebenen Grund.</p>
</section>
</section>

View file

@ -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";
---
<div class="slides">
<Title />
<Introduction />
<Callbacks />
<EventLoop />
<Promises />
<Async />
<Helper />
</div>

View file

@ -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>

View file

@ -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 { &lt;state&gt;: "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 &amp; 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 { &lt;state&gt;: "fulfilled", &lt;value&gt;: 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 { &lt;state&gt;: "rejected", &lt;value&gt;: 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 &amp; 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 &amp; .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>

View file

@ -0,0 +1,3 @@
<section>
<h1>JavaScript: Asynchroner Code</h1>
</section>

View file

@ -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>