Synchronous and Asynchronous JavaScript - Deel 1
synchrone en asynchrone zijn verwarrende concepten in JavaScript, vooral voor beginners. Er zijn twee of meer dingen synchrone wanneer zij gebeuren op hetzelfde moment (synchroon), en asynchroon als ze dat niet doen (niet synchroon).
Hoewel deze definities gemakkelijk in te nemen zijn, is het eigenlijk ingewikkelder dan het lijkt. We moeten rekening houden met wat zijn precies synchroon, en wat niet.
Je zou waarschijnlijk een a bellen normaal
functioneren in JavaScript synchroon, toch? En als het zoiets is setTimeout ()
of AJAX waarmee je werkt, je zult het asynchroon noemen, ja? Wat als ik je dat vertel beide zijn op een bepaalde manier asynchroon?
Om het te verklaren waarom, we moeten de heer X om hulp vragen.
Scenario 1 - Dhr. X probeert synchroniciteit
Dit is de setup:
- De heer X is iemand die moeilijke vragen kan beantwoorden en elke gevraagde taak kan uitvoeren.
- De enige manier om contact met hem op te nemen is via een telefoontje.
- Welke vraag of taak je ook hebt, om de hulp van Mr X te vragen om het uit te voeren; jij belt hem.
- Mr X geeft je het antwoord of voltooit de taak meteen, en laat het je weten het is klaar.
- Je zet de ontvanger tevreden met zijn inhoud en gaat op stap voor een film.
Wat je net hebt uitgevoerd was een synchrone (heen en weer) communicatie met de heer X. Hij luisterde terwijl u hem uw vraag stelde en u luisterde toen hij antwoord gaf.
Scenario 2 - Meneer X is niet blij met synchroniciteit
Aangezien de heer X zo efficiënt is, begint hij veel meer oproepen te ontvangen. Dus wat gebeurt er als je hem maar belt hij is al bezig met iemand anders praten? Je zult hem je vraag niet kunnen stellen - niet voordat hij vrij is om je telefoontje te ontvangen. Alles wat u hoort is een bezettoon.
Dus wat kan mijnheer X doen om dit te bestrijden?
In plaats van direct te bellen:
- Mr X neemt een nieuwe aan, Mr M. en geeft hem een antwoordapparaat voor de bellers om berichten achter te laten.
- Het is de taak van mijnheer M geef een bericht door van het antwoordapparaat tot Mr X als hij eenmaal weet dat Mr X alle vorige berichten volledig heeft verwerkt en dat al is vrij om een nieuwe te nemen.
- Dus als je hem nu belt, mag je in plaats van een bezettoon te horen een bericht achterlaten voor meneer X wacht op hem om je terug te bellen (nog geen filmtijd).
- Zodra meneer X klaar is met alle berichten in de wachtrij die hij voor je heeft ontvangen, zal hij je probleem onderzoeken, en bel je terug om je een antwoord te geven.
Nu hier ligt de vraag: waren de acties tot nu toe synchroon of asynchroon?
Het is gemengd. Toen je je bericht achterliet, Meneer X luisterde er niet naar, dus de vierde communicatie was asynchroon.
Maar toen hij antwoordde, je was daar aan het luisteren, welke maakt de retourcommunicatie synchroon.
Ik hoop dat je inmiddels een beter begrip hebt gekregen van hoe synchroniciteit wordt waargenomen in termen van communicatie. Tijd om JavaScript binnen te halen.
JavaScript - een asynchrone programmeertaal
Wanneer iemand JavaScript asynchroon kenmerkt, is waar het in het algemeen over gaat hoe u dit kunt doen laat een bericht achter ervoor en uw oproep niet blokkeren met een bezette toon.
De functie-aanroepen zijn nooit direct in JavaScript, ze zijn letterlijk klaar via berichten.
JavaScript gebruikt a berichtenwachtrij waar inkomende berichten (of evenementen) worden gehouden. Een event-lus (een berichtendispatcher) verzendt deze berichten achtereenvolgens naar a oproepstapel waar de overeenkomstige functies van de berichten zijn gestapeld als frames (functieargumenten & variabelen) voor uitvoering.
De call stack bevat het frame van de oorspronkelijke functie die wordt aangeroepen en eventuele andere frames voor functies die worden aangeroepen via geneste oproepen daar bovenop .
Wanneer een bericht in de wachtrij wordt geplaatst, wacht het totdat de oproepstapel is leeg van alle frames van het vorige bericht, en wanneer het is, de gebeurtenis-lus verwijdert het vorige bericht, en voegt de corresponderende frames van het huidige bericht toe aan de oproepstapel.
Het bericht wacht opnieuw tot de oproepstack wordt leeg van zijn eigen corresponderende frames (dat wil zeggen dat de uitvoeringen van alle gestapelde functies voorbij zijn), dan wordt uit de wachtrij geplaatst.
Beschouw de volgende code:
functie foo () functiebalk () foo (); functie baz () bar (); baz ();
De functie die wordt uitgevoerd is baz ()
(op de laatste rij van het codefragment), waarvoor een bericht wordt toegevoegd aan de wachtrij, en wanneer de event-lus het oppakt, de oproepstack begint met het stapelen van frames voor baz ()
, bar()
, en foo ()
op de relevante punten van uitvoering.
Nadat de uitvoering van de functies één voor één is voltooid, zijn hun frames dat verwijderd uit de call stack, terwijl het bericht is wacht nog steeds in de wachtrij, tot baz ()
wordt uit de stapel gehaald.
Vergeet niet dat de functie-aanroepen zijn nooit direct in JavaScript, ze zijn klaar via berichten. Dus als je iemand hoort zeggen dat JavaScript zelf een asynchrone programmeertaal is, neem dan aan dat ze het hebben over de ingebouwde taal “antwoordapparaat”, en hoe je vrij bent om berichten achter te laten.
Maar hoe zit het met de specifieke asynchrone methoden?
Tot nu toe heb ik geen gebruik gemaakt van API's zoals setTimeout ()
en AJAX, dat zijn degenen die dat zijn specifiek aangeduid als asynchroon. Waarom is dat?
Het is belangrijk om te begrijpen wat precies synchroon of asynchroon is. JavaScript kan oefenen met behulp van evenementen en de gebeurtenis-lus asynchrone verwerking van berichten, maar dat betekent niet alles in JavaScript is asynchroon.
Vergeet niet dat ik je vertelde dat het bericht niet wegging totdat de call stack was leeg van de bijbehorende frames, net zoals je niet naar een film ging voordat je je antwoord kreeg - dat is het synchroon zijn, je bent daar aan het wachten totdat de taak is voltooid, en je krijgt het antwoord.
Aan het wachten is niet ideaal in alle scenario's. Wat als er na het verlaten van een bericht in plaats van te wachten, je naar de film kunt gaan? Wat als een functie kan stoppen (de oproepstapel legen) en het bericht kan worden uitgezet voordat de taak van de functie is voltooid? Wat als je code asynchroon kan laten uitvoeren??
Dit is waar API's zoals setTimeout ()
en AJAX komen in beeld, en wat ze doen is ... wacht even, ik kan dit niet uitleggen zonder terug te gaan naar mijnheer X, wat we in het tweede deel van dit artikel zullen zien. Blijf kijken.