Async / Warten und Versprechen erklärt

Die Operatoren async/ awaiterleichtern die Implementierung vieler asynchroner Versprechen. Sie ermöglichen es Ingenieuren auch, klareren, prägnanteren und testbaren Code zu schreiben.

Um dieses Thema zu verstehen, sollten Sie ein solides Verständnis dafür haben, wie Versprechen funktionieren.

Grundlegende Syntax

function slowlyResolvedPromiseFunc(string) { return new Promise(resolve => { setTimeout(() => { resolve(string); }, 5000); }); } async function doIt() { const myPromise = await slowlyResolvedPromiseFunc("foo"); console.log(myPromise); // "foo" } doIt();

Es gibt ein paar Dinge zu beachten:

  • Die Funktion, die die awaitDeklaration umfasst, muss den asyncOperator enthalten. Dadurch wird dem JS-Interpreter mitgeteilt, dass er warten muss, bis das Versprechen aufgelöst oder abgelehnt wird.
  • Der awaitOperator muss während der const-Deklaration inline sein.
  • Dies funktioniert rejectgenauso gut wie resolve.

Verschachtelte Promises vs. Async/Await

Das Implementieren eines einzelnen Versprechens ist ziemlich einfach. Im Gegensatz dazu können verkettete Versprechen oder die Erstellung eines Abhängigkeitsmusters „Spaghetti-Code“ erzeugen.

In den folgenden Beispielen wird davon ausgegangen, dass die request-promiseBibliothek als verfügbar ist rp.

Verkettete / verschachtelte Versprechen

// First Promise const fooPromise = rp("//domain.com/foo"); fooPromise.then(resultFoo => { // Must wait for "foo" to resolve console.log(resultFoo); const barPromise = rp("//domain.com/bar"); const bazPromise = rp("//domain.com/baz"); return Promise.all([barPromise, bazPromise]); }).then(resultArr => { // Handle "bar" and "baz" resolutions here console.log(resultArr[0]); console.log(resultArr[1]); });

asyncund awaitVersprechen

// Wrap everything in an async function async function doItAll() { // Grab data from "foo" endpoint, but wait for resolution console.log(await rp("//domain.com/foo")); // Concurrently kick off the next two async calls, // don't wait for "bar" to kick off "baz" const barPromise = rp("//domain.com/bar"); const bazPromise = rp("//domain.com/baz"); // After both are concurrently kicked off, wait for both const barResponse = await barPromise; const bazResponse = await bazPromise; console.log(barResponse); console.log(bazResponse); } // Finally, invoke the async function doItAll().then(() => console.log('Done!'));

Die Vorteile der Verwendung asyncund awaitsollten klar sein. Dieser Code ist besser lesbar, modular und testbar.

Es ist fair zu bemerken, dass der zugrunde liegende Rechenprozess derselbe ist wie im vorherigen Beispiel, obwohl ein zusätzliches Gefühl der Parallelität besteht.

Umgang mit Fehlern / Ablehnung

Ein einfacher Try-Catch-Block verarbeitet ein abgelehntes Versprechen.

async function errorExample() { try { const rejectedPromise = await Promise.reject("Oh-oh!"); } catch (error) { console.log(error); // "Uh-oh!" } } errorExample();