De auteur heeft het Open Internet/Free Speech Fund geselecteerd om een donatie te ontvangen als onderdeel van het Write for DOnations-programma.
Inleiding
Voor veel programma’s in JavaScript wordt code uitgevoerd terwijl de ontwikkelaar deze schrijft, regel voor regel. Dit wordt synchroon uitvoeren genoemd, omdat de regels na elkaar worden uitgevoerd, in de volgorde waarin ze zijn geschreven. Niet elke instructie die u aan de computer geeft, hoeft echter onmiddellijk te worden uitgevoerd. Als u bijvoorbeeld een netwerkverzoek verzendt, moet het proces dat uw code uitvoert wachten tot de gegevens terugkomen voordat het eraan kan werken. In dit geval zou tijd verspild worden als er geen andere code werd uitgevoerd terwijl werd gewacht op de voltooiing van het netwerkverzoek. Om dit probleem op te lossen, gebruiken ontwikkelaars asynchroon programmeren, waarbij regels code in een andere volgorde worden uitgevoerd dan waarin ze zijn geschreven. Met asynchroon programmeren kunnen we andere code uitvoeren terwijl we wachten op lange activiteiten zoals netwerkverzoeken om te voltooien.
JavaScript-code wordt uitgevoerd op een enkele thread binnen een computerproces. De code wordt synchroon verwerkt op deze thread, waarbij slechts één instructie tegelijk wordt uitgevoerd. Daarom wordt, als we een langdurige taak op deze thread zouden uitvoeren, de resterende code geblokkeerd totdat de taak is voltooid. Door gebruik te maken van de asynchrone programmeerfuncties van JavaScript kunnen we langdurige taken verplaatsen naar een achtergrondthread om dit probleem te vermijden. Wanneer de taak is voltooid, wordt de code die we nodig hebben om de gegevens van de taak te verwerken teruggeplaatst op de hoofdthread.
In deze tutorial leer je hoe JavaScript asynchrone taken beheert met behulp van de Event Loop, die een JavaScript-constructie is die een nieuwe taak voltooit terwijl hij wacht op een andere. Vervolgens maak je een programma dat asynchrone programmering gebruikt om een lijst met films op te vragen van een Studio Ghibli API en de gegevens opslaat in een CSV-bestand. De asynchrone code zal op drie manieren worden geschreven: callbacks, promises en met de async
/await
-zoekwoorden.
Opmerking: Ten tijde van dit schrijven wordt asynchrone programmering niet langer alleen gedaan met callbacks, maar het leren van deze verouderde methode kan veel context bieden voor waarom de JavaScript-community nu promises gebruikt. De async
/await
-zoekwoorden stellen ons in staat om promises op een minder omslachtige manier te gebruiken, en zijn dus de standaardmanier om asynchrone programmering in JavaScript te doen op het moment van schrijven van dit artikel.
Vereisten
- Node.js geïnstalleerd op uw ontwikkelingsmachine. Deze tutorial maakt gebruik van versie 10.17.0. Om dit te installeren op macOS of Ubuntu 18.04, volg de stappen in Hoe Node.js te installeren en een lokale ontwikkelomgeving te maken op macOS of de sectie Installeren met behulp van een PPA van Hoe Node.js te installeren op Ubuntu 18.04.
- U moet ook bekend zijn met het installeren van pakketten in uw project. Kom op snelheid door onze gids te lezen over Hoe Node.js-modules te gebruiken met npm en package.json.
- Het is belangrijk dat u comfortabel bent met het maken en uitvoeren van functies in JavaScript voordat u leert hoe u ze asynchroon kunt gebruiken. Als u een introductie of opfriscursus nodig heeft, kunt u onze gids lezen over Hoe functies te definiëren in JavaScript
De Event Loop
De Event Loop
Laten we beginnen met het bestuderen van de interne werkingen van de JavaScript-functie-uitvoering. Het begrijpen van hoe dit werkt, zal je in staat stellen om asynchroon code meer doelbewust te schrijven en zal je helpen bij het oplossen van problemen met code in de toekomst.
Terwijl de JavaScript-interpreter de code uitvoert, wordt elke aangeroepen functie toegevoegd aan JavaScript’s call stack. De call stack is een stack – een lijstachtige datastructuur waar items alleen aan de top kunnen worden toegevoegd en van de top kunnen worden verwijderd. Stacks volgen het principe “Laatst ingewisseld, eerst uitgewisseld” of LIFO. Als je twee items op de stack toevoegt, wordt het meest recent toegevoegde item als eerste verwijderd.
Laten we dit illustreren met een voorbeeld met de call stack. Als JavaScript een functie functionA()
tegenkomt die wordt aangeroepen, wordt deze toegevoegd aan de call stack. Als die functie functionA()
een andere functie functionB()
aanroept, wordt functionB()
bovenaan de call stack toegevoegd. Terwijl JavaScript de uitvoering van een functie voltooit, wordt deze verwijderd uit de call stack. Daarom zal JavaScript functionB()
eerst uitvoeren, deze verwijderen uit de stack wanneer deze voltooid is en vervolgens de uitvoering van functionA()
voltooien en deze verwijderen uit de call stack. Dit is de reden waarom inner functies altijd eerder worden uitgevoerd dan hun outer functies.
Wanneer JavaScript een asynchrone bewerking tegenkomt, zoals het schrijven naar een bestand, voegt het deze toe aan een tabel in het geheugen. Deze tabel slaat de bewerking op, de voorwaarde voor voltooiing ervan, en de functie die moet worden aangeroepen wanneer deze is voltooid. Naarmate de bewerking wordt voltooid, voegt JavaScript de bijbehorende functie toe aan de berichtenwachtrij. Een wachtrij is een andere lijstachtige gegevensstructuur waarin items alleen aan de onderkant kunnen worden toegevoegd maar vanaf de bovenkant kunnen worden verwijderd. In de berichtenwachtrij, als twee of meer asynchrone bewerkingen klaar zijn voor uitvoering van hun functies, zal de asynchrone bewerking die als eerste is voltooid, als eerste worden gemarkeerd voor uitvoering.
Functies in de berichtenwachtrij wachten om aan de oproepstapel te worden toegevoegd. De gebeurtenislus is een eeuwigdurend proces dat controleert of de oproepstapel leeg is. Als dat het geval is, wordt het eerste item in de berichtenwachtrij naar de oproepstapel verplaatst. JavaScript geeft prioriteit aan functies in de berichtenwachtrij boven functieaanroepen die het in de code interpreteert. Het gecombineerde effect van de oproepstapel, berichtenwachtrij en gebeurtenislus maakt het mogelijk dat JavaScript-code wordt verwerkt terwijl asynchrone activiteiten worden beheerd.
Nu je een globaal begrip hebt van de gebeurtenislus, weet je hoe de asynchrone code die je schrijft zal worden uitgevoerd. Met deze kennis kun je nu asynchrone code maken met drie verschillende benaderingen: terugbellen, beloftes, en async
/await
.
Asynchrone Programmering met Terugbellen
A callback function is one that is passed as an argument to another function, and then executed when the other function is finished. We use callbacks to ensure that code is executed only after an asynchronous operation is completed.
Voor een lange tijd waren terugbellen het meest voorkomende mechanisme voor het schrijven van asynchrone code, maar nu zijn ze grotendeels verouderd omdat ze de code verwarrend kunnen maken om te lezen. In deze stap schrijf je een voorbeeld van asynchrone code met behulp van terugbellen zodat je het kunt gebruiken als basis om de verhoogde efficiëntie van andere strategieën te zien.
Er zijn veel manieren om terugbel functies te gebruiken in een andere functie. Over het algemeen hebben ze deze structuur:
Hoewel het niet syntactisch vereist is door JavaScript of Node.js om de terugbel functie als het laatste argument van de buitenste functie te hebben, is het een gangbare praktijk die het identificeren van terugbellen gemakkelijker maakt. Het is ook gebruikelijk voor JavaScript-ontwikkelaars om een anonieme functie te gebruiken als een terugbel. Anonieme functies zijn die gemaakt zijn zonder naam. Het is meestal veel leesbaarder wanneer een functie wordt gedefinieerd aan het einde van de argumentenlijst.
Om terugbellen te demonstreren, laten we een Node.js-module maken die een lijst van Studio Ghibli films naar een bestand schrijft. Maak eerst een map aan waarin ons JavaScript-bestand en de uitvoer worden opgeslagen:
Vervolgens ga je naar die map:
We beginnen met het maken van een HTTP-verzoek naar de Studio Ghibli API, waar onze terugbel functie de resultaten van zal loggen. Om dit te doen, zullen we een bibliotheek installeren die ons in staat stelt om de gegevens van een HTTP-respons in een terugbel functie te benaderen.
In je terminal, initialiseer npm zodat we later een referentie hebben voor onze pakketten:request
Dan, installeer de request
bibliotheek:
Open nu een nieuw bestand genaamd callbackMovies.js
in een teksteditor zoals nano
:
In uw teksteditor, voer het volgende code in. Laten we beginnen met het verzenden van een HTTP-verzoek met de request
module:
In de eerste regel laden we de request
module die is geïnstalleerd via npm. De module retourneert een functie die HTTP-verzoeken kan maken; we slaan vervolgens die functie op in de request
constante.
We maken vervolgens het HTTP-verzoek met behulp van de request()
functie. Laten we nu de gegevens van het HTTP-verzoek naar de console afdrukken door de gemarkeerde wijzigingen toe te voegen:
Wanneer we de request()
functie gebruiken, geven we het twee parameters:
- De URL van de website die we proberen te verzoeken
- A callback function that handles any errors or successful responses after the request is complete
Onze callback-functie heeft drie argumenten: error
, response
en body
. Wanneer het HTTP-verzoek voltooid is, worden de argumenten automatisch waarden gegeven afhankelijk van het resultaat. Als het verzoek niet kon worden verzonden, dan zou error
een object bevatten, maar response
en body
zouden null
zijn. Als het het verzoek succesvol heeft gemaakt, dan wordt de HTTP-respons opgeslagen in response
. Als onze HTTP-respons gegevens retourneert (in dit voorbeeld krijgen we JSON), dan wordt de gegevens ingesteld in body
.
Onze terugroepfunctie controleert eerst of we een fout hebben ontvangen. Het is een goede praktijk om eerst op fouten te controleren in een terugroepfunctie, zodat de uitvoering van de terugroepfunctie niet doorgaat met ontbrekende gegevens. In dit geval loggen we de fout en de uitvoering van de functie. Vervolgens controleren we de statuscode van de respons. Onze server is mogelijk niet altijd beschikbaar en API’s kunnen veranderen, waardoor eens zinvolle verzoeken onjuist kunnen worden. Door te controleren of de statuscode 200
is, wat betekent dat het verzoek “OK” was, kunnen we er vertrouwen in hebben dat onze respons is wat we verwachten.
Tenslotte parseren we de responsbody naar een Array
en lopen we door elke film om de naam en het releasejaar te loggen.
Na het opslaan en afsluiten van het bestand, voer dit script uit met:
Je krijgt de volgende uitvoer:
OutputCastle in the Sky, 1986
Grave of the Fireflies, 1988
My Neighbor Totoro, 1988
Kiki's Delivery Service, 1989
Only Yesterday, 1991
Porco Rosso, 1992
Pom Poko, 1994
Whisper of the Heart, 1995
Princess Mononoke, 1997
My Neighbors the Yamadas, 1999
Spirited Away, 2001
The Cat Returns, 2002
Howl's Moving Castle, 2004
Tales from Earthsea, 2006
Ponyo, 2008
Arrietty, 2010
From Up on Poppy Hill, 2011
The Wind Rises, 2013
The Tale of the Princess Kaguya, 2013
When Marnie Was There, 2014
We hebben met succes een lijst ontvangen van Studio Ghibli-films met het jaar van uitgave. Laten we dit programma voltooien door de filmlijst die we momenteel aan het registreren zijn, in een bestand te schrijven.
Update het bestand callbackMovies.js
in je teksteditor om de volgende gemarkeerde code op te nemen, die een CSV-bestand met onze filmgegevens maakt:
Met de gemarkeerde wijzigingen in gedachten zien we dat we de fs
-module importeren. Deze module is standaard in alle Node.js-installaties en bevat een writeFile()
-methode die asynchroon naar een bestand kan schrijven.
In plaats van de gegevens naar de console te loggen, voegen we deze nu toe aan een stringvariabele `movieList
`. Vervolgens gebruiken we writeFile()
om de inhoud van movieList
op te slaan in een nieuw bestand – callbackMovies.csv
. Ten slotte bieden we een callback aan voor de writeFile()
functie, die één argument heeft: error
. Dit stelt ons in staat om gevallen te behandelen waarin we niet in staat zijn om naar een bestand te schrijven, bijvoorbeeld wanneer de gebruiker waarop we het node
proces draaien, niet over die rechten beschikt.
Sla het bestand op en voer dit Node.js-programma opnieuw uit met:
In je ghibliMovies
-map zie je callbackMovies.csv
, met de volgende inhoud:
Castle in the Sky, 1986
Grave of the Fireflies, 1988
My Neighbor Totoro, 1988
Kiki's Delivery Service, 1989
Only Yesterday, 1991
Porco Rosso, 1992
Pom Poko, 1994
Whisper of the Heart, 1995
Princess Mononoke, 1997
My Neighbors the Yamadas, 1999
Spirited Away, 2001
The Cat Returns, 2002
Howl's Moving Castle, 2004
Tales from Earthsea, 2006
Ponyo, 2008
Arrietty, 2010
From Up on Poppy Hill, 2011
The Wind Rises, 2013
The Tale of the Princess Kaguya, 2013
When Marnie Was There, 2014
Het is belangrijk om op te merken dat we naar ons CSV-bestand schrijven in de callback van het HTTP-verzoek. Zodra de code in de callback-functie staat, zal deze pas naar het bestand schrijven nadat het HTTP-verzoek is voltooid. Als we na het schrijven van ons CSV-bestand naar een database wilden communiceren, zouden we een andere asynchrone functie maken die wordt aangeroepen in de callback van writeFile()
. Hoe meer asynchrone code we hebben, hoe meer callback-functies er genest moeten worden.
Laten we ons voorstellen dat we vijf asynchrone bewerkingen willen uitvoeren, waarvan er telkens één alleen kan worden uitgevoerd wanneer een andere is voltooid. Als we dit zouden coderen, zouden we iets hebben als dit:
Wanneer geneste callbacks veel regels code moeten uitvoeren, worden ze aanzienlijk complexer en onleesbaar. Naarmate je JavaScript-project groeit in omvang en complexiteit, zal dit effect meer uitgesproken worden, totdat het uiteindelijk onbeheersbaar wordt. Hierdoor gebruiken ontwikkelaars niet langer callbacks om asynchrone bewerkingen te verwerken. Om de syntaxis van onze asynchrone code te verbeteren, kunnen we in plaats daarvan beloftes gebruiken.
Het Gebruik van Beloftes voor Beknopte Asynchrone Programmering
A promise is a JavaScript object that will return a value at some point in the future. Asynchronous functions can return promise objects instead of concrete values. If we get a value in the future, we say that the promise was fulfilled. If we get an error in the future, we say that the promise was rejected. Otherwise, the promise is still being worked on in a pending state.
Beloftes hebben over het algemeen de volgende vorm:
Zoals te zien is in dit sjabloon, gebruiken beloftes ook callbackfuncties. We hebben een callbackfunctie voor de then()
-methode, die wordt uitgevoerd wanneer een belofte wordt vervuld. We hebben ook een callbackfunctie voor de catch()
-methode om eventuele fouten af te handelen die optreden tijdens de uitvoering van de belofte.
Laten we uit de eerste hand ervaring opdoen met beloftes door ons Studio Ghibli-programma opnieuw te schrijven om beloftes te gebruiken.
Axios is een op beloftes gebaseerde HTTP-client voor JavaScript, dus laten we het installeren:
En nu, met je teksteditor naar keuze, maak een nieuw bestand promiseMovies.js
:
Ons programma zal een HTTP-verzoek doen met axios
en vervolgens een speciale op beloftes gebaseerde versie van fs
gebruiken om naar een nieuw CSV-bestand op te slaan.
Type deze code in promiseMovies.js
zodat we Axios kunnen laden en een HTTP-verzoek naar de film-API kunnen sturen:
In de eerste regel laden we de axios
-module, waarbij we de geretourneerde functie opslaan in een constante genaamd axios
. Vervolgens gebruiken we de axios.get()
-methode om een HTTP-verzoek naar de API te sturen.
De axios.get()
-methode retourneert een belofte. Laten we die belofte ketenen zodat we de lijst met Ghibli-films naar de console kunnen afdrukken:
Laten we eens kijken wat er gebeurt. Nadat we een HTTP GET-verzoek hebben gemaakt met axios.get()
, gebruiken we de then()
-functie, die alleen wordt uitgevoerd wanneer de belofte wordt vervuld. In dit geval drukken we de films af op het scherm zoals we deden in het voorbeeld met terugroepfuncties.
Om dit programma te verbeteren, voeg je de gemarkeerde code toe om de HTTP-gegevens naar een bestand te schrijven:
We importeren additioneel opnieuw de fs
-module. Let op hoe we na de import van fs
.promises
hebben. Node.js bevat een op beloften gebaseerde versie van de op terugroepfuncties gebaseerde fs
-bibliotheek, dus de achterwaartse compatibiliteit wordt niet verbroken in oudere projecten.
De eerste then()
-functie die het HTTP-verzoek verwerkt roept nu fs.writeFile()
aan in plaats van naar de console te printen. Omdat we de op beloften gebaseerde versie van fs
hebben geïmporteerd, retourneert onze writeFile()
-functie een andere belofte. Als zodanig voegen we nog een then()
-functie toe voor wanneer de belofte van writeFile()
wordt vervuld.
A promise can return a new promise, allowing us to execute promises one after the other. This paves the way for us to perform multiple asynchronous operations. This is called promise chaining, and it is analogous to nesting callbacks. The second then()
is only called after we successfully write to the file.
Opmerking: In dit voorbeeld hebben we niet gecontroleerd op de HTTP-statuscode zoals we deden in het callback-voorbeeld. Standaard voldoet axios
niet aan zijn belofte als het een statuscode krijgt die duidt op een fout. Daarom hoeven we het niet langer te valideren.
Om dit programma te voltooien, keten de belofte met een catch()
-functie zoals hieronder wordt aangegeven:
Als een belofte niet wordt nagekomen in de keten van beloftes, gaat JavaScript automatisch naar de catch()
-functie als deze is gedefinieerd. Daarom hebben we slechts één catch()
-clausule, ook al hebben we twee asynchrone bewerkingen.
Laten we bevestigen dat ons programma dezelfde uitvoer produceert door het volgende uit te voeren:
In uw ghibliMovies
-map ziet u het bestand promiseMovies.csv
met daarin:
Castle in the Sky, 1986
Grave of the Fireflies, 1988
My Neighbor Totoro, 1988
Kiki's Delivery Service, 1989
Only Yesterday, 1991
Porco Rosso, 1992
Pom Poko, 1994
Whisper of the Heart, 1995
Princess Mononoke, 1997
My Neighbors the Yamadas, 1999
Spirited Away, 2001
The Cat Returns, 2002
Howl's Moving Castle, 2004
Tales from Earthsea, 2006
Ponyo, 2008
Arrietty, 2010
From Up on Poppy Hill, 2011
The Wind Rises, 2013
The Tale of the Princess Kaguya, 2013
When Marnie Was There, 2014
Met beloftes kunnen we veel beknopter code schrijven dan wanneer we alleen terugroepfuncties gebruiken. De belofteketen van terugroepfuncties is een schonere optie dan het nesten van terugroepfuncties. Naarmate we echter meer asynchrone oproepen doen, wordt onze belofteketen langer en moeilijker te onderhouden.
De uitgebreidheid van terugroepfuncties en beloftes komt voort uit de noodzaak om functies te maken wanneer we het resultaat van een asynchrone taak hebben. Een betere ervaring zou zijn om te wachten op een asynchroon resultaat en dit in een variabele buiten de functie te plaatsen. Op die manier kunnen we de resultaten in de variabelen gebruiken zonder een functie te hoeven maken. We kunnen dit bereiken met de sleutelwoorden async
en await
.
Het schrijven van JavaScript met async
/await
De sleutelwoorden async
/await
bieden een alternatieve syntaxis bij het werken met beloftes. In plaats van het resultaat van een belofte beschikbaar te hebben in de methode then()
, wordt het resultaat geretourneerd als een waarde, net als bij elke andere functie. We definiëren een functie met het sleutelwoord async
om JavaScript te vertellen dat het een asynchrone functie is die een belofte retourneert. We gebruiken het sleutelwoord await
om JavaScript te vertellen de resultaten van de belofte terug te geven in plaats van de belofte zelf wanneer deze is vervuld.
In het algemeen ziet het gebruik van async
/await
er als volgt uit:
Laten we eens kijken hoe het gebruik van async
/await
ons Studio Ghibli-programma kan verbeteren. Gebruik uw teksteditor om een nieuw bestand te maken en te openen met de naam asyncAwaitMovies.js
:
In uw zojuist geopende JavaScript-bestand, laten we beginnen met het importeren van dezelfde modules die we hebben gebruikt in ons voorbeeld met beloftes:
De imports zijn hetzelfde als bij promiseMovies.js
omdat async
/await
beloftes gebruikt.
Nu gebruiken we het sleutelwoord async
om een functie te maken met onze asynchrone code:
We creëren een nieuwe functie genaamd saveMovies()
, maar we voegen async
toe aan het begin van de definitie. Dit is belangrijk omdat we alleen het await
-trefwoord kunnen gebruiken in een asynchrone functie.
Gebruik het await
-trefwoord om een HTTP-verzoek te maken dat de lijst met films ophaalt van de Ghibli API:
In onze saveMovies()
-functie maken we een HTTP-verzoek met axios.get()
zoals eerder. Deze keer ketenen we het niet met een then()
-functie. In plaats daarvan voegen we await
toe voordat het wordt aangeroepen. Wanneer JavaScript await
ziet, zal het pas de resterende code van de functie uitvoeren nadat axios.get()
is uitgevoerd en de response
-variabele heeft ingesteld. De andere code slaat de filmgegevens op zodat we naar een bestand kunnen schrijven.
Laten we de filmgegevens naar een bestand schrijven:
We gebruiken ook het await
-trefwoord wanneer we naar het bestand schrijven met fs.writeFile()
.
Om deze functie te voltooien, moeten we fouten afhandelen die onze beloftes kunnen veroorzaken. Laten we dit doen door onze code in een try
/catch
-blok in te sluiten:
Aangezien beloftes kunnen mislukken, omhullen we onze asynchrone code met een try
/catch
-clausule. Dit zal eventuele fouten vastleggen die worden veroorzaakt wanneer zowel het HTTP-verzoek als de bestandsschrijfoperaties mislukken.
Tenslotte, laten we onze asynchrone functie saveMovies()
aanroepen zodat deze wordt uitgevoerd wanneer we het programma uitvoeren met node
.
Op het eerste gezicht lijkt dit op een typisch blok synchrone JavaScript-code. Er worden minder functies doorgegeven, wat er wat netter uitziet. Deze kleine aanpassingen maken asynchrone code met async
/await
gemakkelijker te onderhouden.
Test deze iteratie van ons programma door dit in uw terminal in te voeren:
In uw map ghibliMovies
wordt een nieuw bestand asyncAwaitMovies.csv
aangemaakt met de volgende inhoud:
Castle in the Sky, 1986
Grave of the Fireflies, 1988
My Neighbor Totoro, 1988
Kiki's Delivery Service, 1989
Only Yesterday, 1991
Porco Rosso, 1992
Pom Poko, 1994
Whisper of the Heart, 1995
Princess Mononoke, 1997
My Neighbors the Yamadas, 1999
Spirited Away, 2001
The Cat Returns, 2002
Howl's Moving Castle, 2004
Tales from Earthsea, 2006
Ponyo, 2008
Arrietty, 2010
From Up on Poppy Hill, 2011
The Wind Rises, 2013
The Tale of the Princess Kaguya, 2013
When Marnie Was There, 2014
U hebt nu de JavaScript-functies async
/await
gebruikt om asynchrone code te beheren.
Conclusie
In deze tutorial hebt u geleerd hoe JavaScript functies uitvoert en asynchrone operaties beheert met behulp van de gebeurteniswachtrij. Vervolgens hebt u programma’s geschreven die een CSV-bestand hebben aangemaakt na het maken van een HTTP-verzoek voor filmgegevens met verschillende asynchrone programmeertechnieken. Eerst gebruikte u de verouderde op callback gebaseerde benadering. Vervolgens gebruikte u beloften en uiteindelijk async
/await
om de belofte-syntaxis beknopter te maken.
Met je begrip van asynchrone code met Node.js kun je nu programma’s ontwikkelen die profiteren van asynchroon programmeren, zoals die welke afhankelijk zijn van API-aanroepen. Bekijk deze lijst met openbare API’s. Om ze te gebruiken, zul je asynchrone HTTP-verzoeken moeten maken zoals we deden in deze tutorial. Voor verdere studie, probeer een app te bouwen die deze API’s gebruikt om de technieken die je hier hebt geleerd te oefenen.
Source:
https://www.digitalocean.com/community/tutorials/how-to-write-asynchronous-code-in-node-js