Synchroon en asynchroon in JavaScript begrijpen - Deel 2
In het eerste deel van dit bericht hebben we gezien hoe het concepten van synchroon en asynchroon worden waargenomen in JavaScript. In dit tweede deel lijkt de heer X ons opnieuw te helpen begrijpen hoe de setTimeout en AJAX APIs werk.
Een vreemd verzoek
Laten we terugspoelen naar het verhaal van Mr X en de film die je wilt verlaten. Stel dat je een taak voor Mr. X voor het uitje achterlaat, en zeg hem dat hij alleen aan deze taak kan beginnen vijf uur na hij heeft je bericht ontvangen.
Hij is er niet blij mee, onthoud, hij neemt geen nieuwe boodschap totdat hij klaar is met de huidige, en als hij de jouwe neemt, hij moet wachten vijf uur om zelfs maar aan de taak te beginnen. Dus om geen verspilling van tijd te zijn, hij brengt een helper binnen, De heer H.
In plaats van te wachten, vraagt hij de heer H om laat een nieuw bericht achter voor de taak in de wachtrij na de gegeven uren voorbij was gegaan, en gaat verder met het volgende bericht.
Vijf uur voorbij; De heer H werkt de wachtrij bij met een nieuw bericht. Nadat hij alle opgebouwde berichten heeft verwerkt vóór de heer H's, mijnheer X voert uw gevraagde taak uit. Dus, op deze manier kun je een verzoek achterlaten om te zijn op een later tijdstip worden nageleefd, en niet wachten tot het is vervuld.
Maar waarom laat de heer H een bericht achter in de rij in plaats van rechtstreeks contact op te nemen met mijnheer X? Omdat zoals ik in het eerste deel heb genoemd, de enkel en alleen manier om contact op te nemen met Mr X is door een bericht achter te laten via telefoontje - geen uitzonderingen.
1. Het setTimeout ()
methode
Stel dat je een set code hebt die je wilt uitvoeren na een bepaalde tijd. Om dat te doen, doe je gewoon verpak het in een functie, en voeg het toe aan een setTimeout ()
methode samen met de vertragingstijd. De syntaxis van setTimeout ()
is als volgt:
setTimeout (functie, vertragingstijd, arg ...)
De arg ...
parameter staat voor elk argument dat de functie nodig heeft, en vertragingstijd
moet in milliseconden worden toegevoegd. Hieronder ziet u een eenvoudig codevoorbeeld dat uitgaat “Hallo” in de console na 3 seconden.
setTimeout (function () console.log ('hey'), 3000);
Een keer setTimeout ()
begint te rennen, in plaats van de oproepstapel te blokkeren totdat de aangegeven vertragingstijd voorbij is, a timer is geactiveerd, en de oproepstapel wordt geleegd voor het volgende bericht (vergelijkbaar met de correspondentie tussen Mr X en Mr H).
Wanneer de timer afloopt, een nieuw bericht sluit zich aan bij de wachtrij, en de lus van de gebeurtenis pakt deze op als de oproepstapel vrij is na het verwerken van alle berichten ervoor - en dus loopt de code asynchroon.
2. AJAX
AJAX (asynchrone JavaScript en XML) is een concept dat de XMLHttpRequest
(XHR) API voor serververzoeken doen en behandel de antwoorden.
Wanneer browsers serveraanvragen doen zonder XMLHttpRequest te gebruiken, wordt de pagina vernieuwt en laadt zijn gebruikersinterface opnieuw. Wanneer de verwerking van verzoeken en antwoorden wordt afgehandeld door de XHR API, en Gebruikersinterface blijft ongewijzigd.
Dus eigenlijk is het doel om verzoeken doen zonder pagina opnieuw te laden. Nu, waar is het “asynchrone” in deze? Alleen al het gebruik van XHR-code (wat we zo meteen zullen zien) betekent niet dat het AJAX is, omdat de XHR API kan werk op zowel synchrone als asynchrone manieren.
XHR standaard ingesteld op werk asynchroon; wanneer een functie een verzoek doet met behulp van XHR, it keert terug zonder op het antwoord te wachten.
Als XHR is geconfigureerd voor synchroon zijn, dan wacht de functie tot de antwoord wordt ontvangen en verwerkt voordat je terugkeert.
Code Voorbeeld 1
Dit voorbeeld presenteert een XMLHttpRequest
creatie van objecten. De Open()
methode, valideert de aanvraag-URL en de sturen()
methode verzendt het verzoek.
var xhr = nieuwe XMLHttpRequest (); xhr.open ("GET", url); xhr.send ();
Elke directe toegang tot de antwoordgegevens na sturen()
zal tevergeefs zijn, omdat sturen()
wacht niet totdat het verzoek is voltooid. Vergeet niet dat XMLHTTPRequest standaard asynchroon werkt.
Code Voorbeeld 2
De hello.txt
bestand in dit voorbeeld is een eenvoudig tekstbestand met de tekst 'hallo'. De antwoord
eigenschap van XHR ongeldig is, omdat het de tekst 'hallo' niet heeft uitgevoerd.
var xhr = nieuwe XMLHttpRequest (); xhr.open ("GET", "hello.txt"); xhr.send (); document.write (xhr.response); // lege tekenreeks
XHR implementeert een micro-routine die blijft controleren op antwoord in elke milliseconde, en triggert gratis evenementen voor de verschillende staten doorloopt een verzoek. Wanneer het antwoord is geladen, een laadgebeurtenis wordt geactiveerd door XHR, die een geldig antwoord kan opleveren.
var xhr = nieuwe XMLHttpRequest (); xhr.open ("GET", "hello.txt"); xhr.send (); xhr.onload = function () document.write (this.response) // schrijft 'hallo' naar het document
Het antwoord binnen de load-gebeurtenis uitgangen 'hallo', de juiste tekst.
Het gebruik van de asynchrone methode heeft de voorkeur, omdat andere scripts niet worden geblokkeerd totdat het verzoek is voltooid.
Als het antwoord synchroon moet worden verwerkt, gaan we door vals
als het laatste argument van Open
, welke markeert de XHR API zeg het moet synchroon zijn (standaard het laatste argument van Open
is waar
, die je niet expliciet hoeft te specificeren).
var xhr = nieuwe XMLHttpRequest (); xhr.open ("GET", "hello.txt", false); xhr.send (); document.write (xhr.response); // schrijft 'hallo' om te documenteren
Waarom dit allemaal leren?
Bijna alle beginners maken fouten met asynchrone concepten zoals setTimeout ()
en AJAX, bijvoorbeeld door aan te nemen setTimeout ()
voert code uit na de vertragingstijd, of door de reactie direct in een functie te verwerken die een AJAX-aanvraag doet.
Als je weet hoe de puzzel past, kun je dat vermijd dergelijke verwarring. Je weet dat de vertragingstijd binnen is setTimeout ()
geeft niet de tijd aan wanneer de code wordt uitgevoerd, maar de tijd wanneer de timer afloopt en een nieuw bericht in de wachtrij staat, dat alleen wordt verwerkt wanneer de call stack vrij is om dit te doen.