Das Konstrukt async / await ist ein relativ neuer Ansatz zum Schreiben von asynchronem Code in JavaScript. Es basiert auf Versprechungen und blockiert daher nicht den Hauptstrom. Die Innovation dieses Designs besteht darin, dass asynchroner Code dank ihm dem synchronen ähnlich wird und sich ähnlich verhält. Dies eröffnet dem Programmierer große Möglichkeiten.

Vor dem Aufkommen von async / await wurden Rückrufe und Versprechen bei der Entwicklung asynchroner Programmmechanismen verwendet. Der Autor des Materials, dessen Übersetzung wir heute veröffentlichen, schlägt vor, dass Sie sich zuerst daran erinnern, wie man Code auf die alte Weise schreibt, und dann anhand eines realen Beispiels die Verwendung von async / await untersuchen.
Rückrufe
Hier ist ein Beispielcode, der Rückrufe (Rückruffunktionen) verwendet:
setTimeout(() => { console.log('This runs after 1000 milliseconds.'); }, 1000);
Bei Verwendung der verschachtelten Rückruffunktionen tritt ein Problem auf, das als Rückrufhölle bezeichnet wird. Hier ist ein vereinfachtes Codebeispiel, um dieses Problem zu veranschaulichen:
asyncCallOne(() => { asyncCallTwo(() => { asyncCallThree(() => { asyncCallFour(() => { asyncCallFive(() => {
Wenn der Code Strukturen enthält, die aus ineinander verschachtelten Rückrufen bestehen, ist ein solcher Code möglicherweise schwer zu verstehen und schwer zu pflegen.
Versprechen
Hier ist ein Beispielcode, der Versprechen verwendet (Versprechenobjekte):
const promiseFunction = new Promise((resolve, reject) => { const add = (a, b) => a + b; resolve(add(2, 2)); }); promiseFunction.then((response) => { console.log(response); }).catch((error) => { console.log(error); });
Die Funktion
promiseFunction()
aus diesem Beispiel gibt ein
Promise
Objekt zurück, bei dem es sich um eine bestimmte Aktion handelt, die von der Funktion ausgeführt wird. Ein Aufruf der Methode
resolve()
zeigt an, dass der Vorgang erfolgreich abgeschlossen wurde. In solchen Konstruktionen wird auch die Versprechungsmethode
.then()
verwendet. Mit ihrer Hilfe können Sie nach erfolgreicher Lösung des Versprechens einen bestimmten Rückruf ausführen. Die
.catch()
-Methode wird aufgerufen, wenn während der Arbeit des Versprechens ein
.catch()
ist.
Asynchrone Funktionen
Mit dem
async
Funktionen (asynchrone Funktionen) bieten uns die Möglichkeit, Code zu schreiben, der ordentlich und nicht mit Servicekonstrukten überladen ist, sodass wir das gleiche Ergebnis erzielen können, das wir mit Versprechungen erhalten haben. Es sollte beachtet werden, dass das
async
im Wesentlichen nur "syntaktischer Zucker" für Versprechen ist.
Asynchrone Funktionen werden beim Deklarieren einer Funktion mit dem Schlüsselwort
async
erstellt. Es sieht so aus:
const asyncFunction = async () => {
Asynchrone Funktionen können mit dem Schlüsselwort
await
angehalten werden. Es kann nur in asynchronen Funktionen verwendet werden. Sie können das Ergebnis der asynchronen Funktion zurückgeben, das verfügbar ist, nachdem eine solche Funktion die Ausführung einer Aufgabe abgeschlossen hat.
Vergleichen Sie die Operation einer asynchronen Funktion und ein Versprechen, das eine Zeichenfolge zurückgibt:
Es ist leicht zu erkennen, dass Sie mit dem
async
asynchronen Code schreiben können, der synchron aussieht. Dieser Code ist viel einfacher zu bearbeiten.
Nachdem wir die grundlegenden Dinge behandelt haben, fahren wir mit unserem Beispiel fort.
Währungsumrechner
▍ Vorbereitende Vorbereitung
Hier werden wir eine einfache, aber kognitive Perspektive erstellen, um die Konstruktion der asynchronen / wartenden Anwendung zu untersuchen. Es ist ein Währungsumrechner, der reale Daten verwendet, die von den entsprechenden APIs erhalten wurden. Das Programm akzeptiert den Betrag in einer bestimmten Währung, den Code dieser Währung sowie den Währungscode, in den wir diesen Betrag umrechnen möchten. Danach zeigt das Programm das Ergebnis an, indem zuerst die aktuellen Daten zu den Wechselkursen heruntergeladen werden. Das Programm zeigt auch eine Liste der Länder an, in denen Sie Geld in der Währung ausgeben können, in die der angegebene Betrag überwiesen wird.
Insbesondere werden hier Daten aus zwei asynchronen Informationsquellen verwendet:
- Currencylayer.com- Dienst. Auf dieser Site müssen Sie ein kostenloses Konto erstellen und einen Schlüssel für den Zugriff auf die API (API Access Key) erhalten. Von hier aus nehmen wir die Daten, die für die Umrechnung des Betrags von einer Währung in eine andere erforderlich sind.
- Service restcountries.eu . Es kann ohne Registrierung verwendet werden. Von hier laden wir Daten hoch, wo Sie die Währung verwenden können, in die wir den angegebenen Geldbetrag umgerechnet haben.
Erstellen Sie ein neues Verzeichnis und führen Sie den Befehl
npm init
darin aus. Wenn das Programm uns eine Frage zum Namen des zu erstellenden Pakets stellt, werden wir den
currency-converter
einführen. Sie können andere Fragen des Programms nicht beantworten, indem
Enter
als Antwort die
Enter
drücken. Installieren Sie anschließend das Axios-Paket in unserem Projekt, indem
npm install axios --save
Befehl
npm install axios --save
in seinem Verzeichnis
npm install axios --save
. Erstellen Sie eine neue Datei mit dem Namen
currency-converter.js
.
Beginnen wir mit dem Schreiben des Programmcodes, indem wir Axios in dieser Datei verbinden:
const axios = require('axios');
Unser Projekt wird drei asynchrone Funktionen haben. Der erste lädt Währungsdaten. Der zweite lädt Länderdaten. Der dritte sammelt diese Daten, präsentiert sie in einer benutzerfreundlichen Form und zeigt sie auf dem Bildschirm an.
▍ Die erste Funktion ist das asynchrone Laden von Währungsdaten
Erstellen wir eine asynchrone Funktion
getExchangeRate()
, die zwei Argumente
fromCurrency
:
fromCurrency
und
toCurrency
:
const getExchangeRate = async (fromCurrency, toCurrency) => {}
In dieser Funktion müssen wir Daten laden. Mit dem Konstrukt async / await können Sie die empfangenen Daten direkt in eine bestimmte Variable oder Konstante schreiben. Vergessen Sie nicht, sich
auf der Site zu registrieren und einen API-Zugriffsschlüssel zu erhalten, bevor Sie den Code für diese Funktion schreiben. Zum Laden von Daten benötigen wir die folgende Konstruktion:
const response = await axios.get('http://www.apilayer.net/api/live?access_key=[ API]');
Nach Erhalt der Systemantwort befinden sich die benötigten Daten im
response
unter
response.data.quotes
. Hier ist das Fragment des Objekts mit den für uns interessanten Daten (es ist im Programm als
response.data
sichtbar):
{ "success":true, "terms":"https:\/\/currencylayer.com\/terms", "privacy":"https:\/\/currencylayer.com\/privacy", "timestamp":1547891348, "source":"USD", "quotes":{ "USDAED":3.673042, "USDAFN":75.350404, "USDALL":109.203989, ... "USDZWL":322.355011 } }
Platzieren Sie das Objekt mit den Wechselkursen in der
rate
:
const rate = response.data.quotes;
Den Basiswährungscode finden Sie unter
response.data.source
. Wir schreiben den Code der Basiswährung in die Konstante
baseCurrency
:
const baseCurrency = response.data.source;
Da die von dieser API zurückgegebenen Daten standardmäßig den Wechselkurs gegenüber dem US-Dollar (USD) darstellen, erstellen Sie eine konstante
usd
, in die wir das Ergebnis der Division von 1 durch den Wechselkurs schreiben, in dem der Betrag angegeben ist:
const usd = 1 / rate[`${baseCurrency}${fromCurrency}`];
Achten Sie darauf, wie der Schlüssel gebildet wird, anhand dessen wir den Wert des Kurses erhalten. In dem von der API erhaltenen Objekt, dessen Fragment oben angegeben ist, sind die Schlüssel Zeichenfolgen, die mit
USD
und mit dem Code der entsprechenden Währung enden. Da davon ausgegangen wird, dass unser Programm Zeichenfolgenwährungscodes akzeptiert, generieren wir einen Schlüssel, indem wir eine Zeichenfolge verketten, die den Basiswährungscode und die Funktion enthält, die im Parameter
fromCurrency
an die Funktion
fromCurrency
wird.
Um nun den Wechselkurs von
fromCurrency
zu
toCurrence
, multiplizieren wir die Konstante
usd
mit dem Kurs für
toCurrency
. Es sieht so aus:
const exchangeRate = usd * rate[`${baseCurrency}${toCurrency}`];
Infolgedessen geben wir zurück, was in
exchangeRate
. So sieht der vollständige Code aus:
const getExchangeRate = async (fromCurrency, toCurrency) => { try { const response = await axios.get('http://www.apilayer.net/api/live?access_key=[ API]'); const rate = response.data.quotes; const baseCurrency = response.data.source; const usd = 1 / rate[`${baseCurrency}${fromCurrency}`]; const exchangeRate = usd * rate[`${baseCurrency}${toCurrency}`]; return exchangeRate; } catch (error) { throw new Error(`Unable to get currency ${fromCurrency} and ${toCurrency}`); } };
Beachten Sie, dass das reguläre try / catch-Konstrukt verwendet wird, um Fehler zu behandeln, die während der Ausführung der Abfrage auftreten können.
▍ Die zweite Funktion ist das asynchrone Laden von Länderdaten
Unsere zweite Funktion,
getCountries()
, die asynchron Informationen über Länder lädt, in denen Sie die Währung verwenden können, in die wir den in einer anderen Währung angegebenen Betrag umrechnen, verwendet das ArgumentrencyCode:
const getCountries = async (currencyCode) => {}
Zum Laden von Daten verwenden wir den folgenden Befehl:
const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`);
Wenn wir zum Beispiel den
HRK
Code (Croatian Kuna) in der Anfrage verwenden, erhalten wir als Antwort einen JSON-Code, von dem ein Fragment unten gezeigt wird:
[ { "name":"Croatia", ... } ]
Es ist eine Reihe von Objekten mit Informationen über Länder. Die Namenseigenschaften dieser Objekte enthalten den Namen des Landes. Sie können mit dem Konstrukt
response.data
auf dieses Array zugreifen. Wir wenden die Array-Methode
map()
an, um die Namen von Ländern aus den empfangenen Daten zu extrahieren und diese Daten von der Funktion
getCountries()
, bei der es sich um ein Array von Ländernamen handelt:
return response.data.map(country => country.name);
Hier ist der vollständige Funktionscode von
getCountries()
:
const getCountries = async (currencyCode) => { try { const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`); return response.data.map(country => country.name); } catch (error) { throw new Error(`Unable to get countries that use ${currencyCode}`); } };
▍Dritte Funktion - Datenerfassung und -ausgabe
Unsere dritte asynchrone Funktion,
convertCurrency ()
, akzeptiert die Argumente von
fromCurrency
,
toCurrency
und
amount
- Währungscodes und Betrag.
const convertCurrency = async (fromCurrency, toCurrency, amount) => {}
Darin erhalten wir zuerst den Wechselkurs:
const exchangeRate = await getExchangeRate(fromCurrency, toCurrency);
Dann laden wir die Liste der Länder:
const countries = await getCountries(toCurrency);
Als nächstes führen wir die Konvertierung durch:
const convertedAmount = (amount * exchangeRate).toFixed(2);
Und nachdem alle erforderlichen Daten gesammelt wurden, geben wir die Zeile zurück, die der Benutzer des Programms sehen wird:
return `${amount} ${fromCurrency} is worth ${convertedAmount} ${toCurrency}. You can spend these in the following countries: ${countries}`;
Hier ist der vollständige Funktionscode:
const convertCurrency = async (fromCurrency, toCurrency, amount) => { const exchangeRate = await getExchangeRate(fromCurrency, toCurrency); const countries = await getCountries(toCurrency); const convertedAmount = (amount * exchangeRate).toFixed(2); return `${amount} ${fromCurrency} is worth ${convertedAmount} ${toCurrency}. You can spend these in the following countries: ${countries}`; };
Bitte beachten Sie, dass diese Funktion keinen Try / Catch-Block hat, da sie nur mit den Ergebnissen der beiden zuvor beschriebenen Funktionen funktioniert.
▍Starten Sie das Programm
Wir haben drei Funktionen vorbereitet, von denen zwei Daten von verschiedenen Diensten laden, und eine sammelt diese Daten und bereitet die Ausgabe vor. Jetzt müssen wir nur noch diese Funktion aufrufen und alles übergeben, was wir brauchen. Wir werden hier keine Mechanismen implementieren, die es ermöglichen, unser Programm über die Befehlszeile mit der Übertragung von Währungs- und Summencodes darauf aufzurufen, obwohl Sie dies tun können, wenn Sie dies wünschen. Wir rufen einfach die Funktion
convertCurrency()
und übergeben ihr die erforderlichen Daten:
convertCurrency('EUR', 'HRK', 20) .then((message) => { console.log(message); }).catch((error) => { console.log(error.message); });
Hier wollen wir herausfinden, wie viel kroatische Kuna gegen 20 Euro eingetauscht werden kann und auf dem Weg herauszufinden, in welchen Ländern dieses Geld ausgegeben werden kann.
Wir rufen das Programm auf, indem wir den folgenden Befehl in das Terminal eingeben:
node currency-converter.js
Als Antwort erhalten wir ungefähr Folgendes.
Das Ergebnis des ProgrammsHier für alle Fälle den vollständigen Code unseres Projekts.
const axios = require('axios'); const getExchangeRate = async (fromCurrency, toCurrency) => { try { const response = await axios.get('http://www.apilayer.net/api/live?access_key=[ API]'); const rate = response.data.quotes; const baseCurrency = response.data.source; const usd = 1 / rate[`${baseCurrency}${fromCurrency}`]; const exchangeRate = usd * rate[`${baseCurrency}${toCurrency}`]; return exchangeRate; } catch (error) { throw new Error(`Unable to get currency ${fromCurrency} and ${toCurrency}`); } }; const getCountries = async (currencyCode) => { try { const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`); return response.data.map(country => country.name); } catch (error) { throw new Error(`Unable to get countries that use ${currencyCode}`); } }; const convertCurrency = async (fromCurrency, toCurrency, amount) => { const exchangeRate = await getExchangeRate(fromCurrency, toCurrency); const countries = await getCountries(toCurrency); const convertedAmount = (amount * exchangeRate).toFixed(2); return `${amount} ${fromCurrency} is worth ${convertedAmount} ${toCurrency}. You can spend these in the following countries: ${countries}`; }; convertCurrency('EUR', 'HRK', 20) .then((message) => { console.log(message); }).catch((error) => { console.log(error.message); });
Zusammenfassung
Wir hoffen, dass dieses Beispiel der Verwendung des Konstrukts async / await unter realen Bedingungen denjenigen geholfen hat, die dieses Konstrukt zuvor nicht verstanden haben, es herauszufinden.
Liebe Leser! Wenn Sie das Konstrukt async / await in der Praxis verwenden, teilen Sie uns bitte Ihre Eindrücke mit.