Hogyan működik az Event Loop JavaScript-ben?

Noha a teljes körű termelési kód írásához szükség lehet olyan nyelvek, mint a C ++ és C alapos megértésére, a JavaScript gyakran egyszerű nyelven írható meg azzal, hogy mit lehet tenni a nyelvtel.


Az olyan fogalmakat, mint például a funkcionális visszahívások átadása vagy az aszinkron kód írása, gyakran nem olyan nehéz megvalósítani, ami a legtöbb JavaScript-fejlesztőt kevésbé érdekli az, ami a motorháztető alatt zajlik. Csak nem törődnek a komplexitások megértésével, amelyeket a nyelv mélyen elvont tőlük.

JavaScript fejlesztőként egyre fontosabbá válik, hogy megértsük, mi történik valójában a motorháztető alatt, és hogy valójában hogyan működnek ezek a tőlünk kivonatolt komplexitások. Segít megalapozottabb döntések meghozatalában, ami drasztikusan javíthatja a kód teljesítményünket.

Ez a cikk a JavaScript egyik nagyon fontos, de ritkán érthető fogalmára vagy kifejezésére összpontosít. Az ESEMÉNY LOOP!. 

Az aszinkron kód írását a JavaScriptben nem lehet elkerülni, de miért jelent valójában az aszinkron módon futó kód? azaz. Az esemény hurok

Mielőtt megérthetnénk az eseményhurok működését, először meg kell értenünk, mi is a JavaScript és hogyan működik!

Mi a JavaScript??

Mielőtt folytatnánk, szeretném, ha tegyünk egy lépést vissza az alapokhoz. Mi az a JavaScript? Meghatározhatjuk a JavaScript-et;

A JavaScript magas szintű, értelmezett, egyszálú, nem blokkoló, aszinkron, párhuzamos nyelv.

Várj, mi ez? Egy könyves meghatározás? ��

Lebontjuk!

A cikk kulcsszavai a következők: egyszálú, nem blokkoló, egyidejű, és aszinkron.

Egyetlen szál

A végrehajtási szál a programozott utasítások legkisebb sorozata, amelyet egy ütemező függetlenül kezelhet. A programozási nyelv egyszálú, azaz csak egy feladatot vagy műveletet képes végrehajtani egyszerre. Ez azt jelenti, hogy egy teljes folyamatot végrehajtana az elejétől a végéig a szál megszakítása vagy leállítása nélkül.

A többszálú nyelvektől eltérően, ahol több folyamat egyidejűleg futhat több szálon anélkül, hogy egymást blokkolnák.

Hogyan lehet a JavaScript egyszálú és nem-blokkoló ugyanabban az időben?

De mit jelent a blokkolás??

Non-blokkoló

A blokkolásnak nincs egy meghatározása; ez egyszerűen azt jelenti, hogy lassan futnak a fonalak. Tehát a nem blokkolás azt jelenti, hogy a menet nem lassú.

De várj, mondtam, hogy a JavaScript egyetlen szálon fut? Azt is mondtam, hogy nem blokkoló, ami azt jelenti, hogy a feladat gyorsan fut a hívásveremben? De hogyan??? Mi lenne, ha időzítőket futtatnánk? Loops?

Nyugi! Kicsit megtudtuk ��.

Egyidejű

Párhuzamosság azt jelenti, hogy a kódot egynél több szál egyidejűleg hajtja végre.

Oké, a dolgok igazán mennek furcsa most, hogy lehet a JavaScript egyszálú és egyszerre egyidejű? vagyis végrehajtja a kódját egynél több szállal?

Aszinkron

Az aszinkron programozás azt jelenti, hogy a kód egy esemény hurokban fut. Blokkoló művelet esetén az esemény elindul. A blokkoló kód folyamatosan fut a fő végrehajtási szál blokkolása nélkül. Amikor a blokkoló kód futtatása befejeződik, a sorban áll a blokkoló műveletek eredménye, és visszahelyezi őket a verembe.

De a JavaScriptnek egyetlen szála van? Akkor végrehajtja ezt a blokkoló kódot, miközben hagyja, hogy a szál többi kódja végrehajtásra kerüljön?

Mielőtt folytatnánk, vessünk át egy áttekintést a fentiekről.

  • A JavaScript egyszálú
  • A JavaScript nem blokkolja, azaz a lassú folyamatok nem blokkolják annak végrehajtását
  • A JavaScript egyidejű, vagyis egyidejűleg több szálban is végrehajtja kódját
  • A JavaScript aszinkron, azaz a blokkoló kódot máshol futtatja.

A fentiek azonban nem adják pontosan, hogyan lehet az egyszálú nyelv nem blokkoló, párhuzamos és aszinkron?

Menjünk egy kicsit mélyebben, menjünk a JavaScript futásidejű motorjaihoz, a V8-hoz, talán van néhány rejtett szála, amiről nem tudunk.

V8 motor

A V8 motor egy nagyteljesítményű, nyílt forráskódú webes összeszerelési futtatómotor JavaScript-hez, amelyet a Google a C ++ nyelven írt. A legtöbb böngésző a V8 motor használatával futtatja a JavaScriptet, sőt a népszerű csomópont js futási környezet is használja.

Egyszerű angol nyelven a V8 egy C ++ program, amely JavaScript kódot fogad, összeállít és végrehajt.

A V8 két fő dolgot csinál;

  • Halommemória elosztása
  • Hívásverem végrehajtási kontextus

Sajnos a gyanúnk helytelen volt. A V8-nak csak egy hívás-verem van, gondolj a hívás-veremre mint szálra.

Egy szál === egy hívásverem === egyszerre egy végrehajtás.

Kép – Hacker dél

Mivel a V8-nak csak egy hívásverem van, hogyan fut a JavaScript egyidejűleg és aszinkron módon, anélkül, hogy blokkolja a fő végrehajtási szálat?

Próbáljuk megtudni egy egyszerű, mégis általános aszinkron kód megírásával, és elemezzük együtt.

A JavaScript mindegyik kódot soronként futtatja, egymás után (egyszálú). Ahogy az várható volt, itt az első sor kinyomtatódik a konzolban, de miért nyomtatják az utolsó sort az időkorlát előtt? Miért nem várja meg a végrehajtási folyamat az időtúllépési kódot (blokkolás), mielőtt folytatná az utolsó sor futtatását?

Úgy tűnik, hogy valami más szál segített bennünket az időtúllépés végrehajtásában, mivel elég biztosak vagyunk abban, hogy egy szál bármikor csak egyetlen feladatot hajthat végre..

Nézzünk be egy betekintést a V8 forráskód egy ideig.

Várj, mi??!!! Nincsenek időzítő funkciók a V8-ban, nincs DOM? Nincsenek események? Nincs AJAX?… Yeeeeessss!!!

Az események, a DOM, az időzítők stb. Nem képezik a JavaScript alapvető megvalósításának részét. A JavaScript szigorúan megfelel az Ecma Scripts előírásainak, és annak különféle verzióira gyakran hivatkoznak az Ecma Scripts Specifikációk (ES X) szerint..

Végrehajtási munkafolyamat

Az eseményeket, időzítőket és az Ajax kérelmeket mind a böngészők az ügyféloldalon biztosítják, és gyakran webes API-nak hivatkoznak. Ezek azok, amelyek lehetővé teszik az egyszálú JavaScript nem blokkoló, párhuzamos és aszinkron! De hogyan?

Három fő szakasz van a JavaScript-programok végrehajtási munkafolyamatában, a hívásveremben, a webes API-ban és a Feladat sorban..

A Call Stack

A verem olyan adatszerkezet, amelyben az utoljára hozzáadott elem mindig az első, amelyet eltávolítanak a veremből, úgy lehet úgy gondolni, mint egy lemez halomára, amelyben csak az első, az utoljára hozzáadott lemez vehető le először. A Call Stack egyszerűen nem más, mint verem adatstruktúra, ahol a feladatok vagy a kód ennek megfelelően hajtódnak végre.

Nézzük meg az alábbi példát;

Forrás – https://youtu.be/8aGhZQkoFbQ

Amikor meghívja a printSquare () függvényt, akkor rákerül a hívásveremre, a printSquare () függvény meghívja a square () függvényt. A négyzet () függvény rákerül a veremre, és meghívja a szorzás () funkciót is. A szorzás funkciót a veremre tolják. Mivel a szorzás funkció visszatér, és ez az utolsó dolog, amelyet a veremhez toltak, először megoldódik, és eltávolításra kerül a veremből, majd a square () függvényt, majd a printSquare () függvényt követi.

A webes API

Ebben az esetben a V8 motor által nem kezelt kód kerül végrehajtásra, hogy ne „blokkolja” a fő végrehajtási szálat. Amikor a Call Stack webes API-funkcióval találkozik, a folyamatot azonnal átadják a Web API-nak, ahol azt végrehajtják, és felszabadítja a Call Stack-t más műveletek végrehajtásához a végrehajtása során.

Térjünk vissza a fenti setTimeout példához;

A kód futtatásakor az első console.log sor átkerül a verembe, és szinte azonnal megkapjuk a kimenetet, amikor elérjük az időtúllépést, az időzítőket a böngésző kezeli, és nem képezik részét a V8 központi megvalósításának. ehelyett felszabadítja a köteget, hogy más műveleteket végezzen.

Amíg az időtúllépés még fut, a verem előrehalad a következő műveleti sorra, és futtatja az utolsó console.log-ot, amely megmagyarázza, hogy miért adjuk ki ezt az időzítő kimenet előtt. Az időzítő befejezése után történik valami. A console.log be, majd az időzítő varázslatosan megjelenik a hívásveremben!

Hogyan?

Az esemény hurok

Mielőtt megbeszéljük az eseményhurkot, először engedjük át a feladatlista funkcióját.

Visszatérve az időtúllépés példájához, amint a Web API befejezi a feladat végrehajtását, nem csak automatikusan tolja vissza a Híváskötegbe. Ez megy a Feladatlista. 

A sor olyan adatszerkezet, amely az „első az elsőből ki” elven működik, tehát amikor a feladatok bekerülnek a sorba, ugyanabban a sorrendben lépnek ki. A Web API által végrehajtott feladatok, amelyeket a Feladat várólistára helyeznek, majd visszatérnek a Híváskötegbe, hogy eredményüket kinyomtassák..

De várj. MI A HAKK AZ ESEMÉNY LOOP???

Forrás – https://youtu.be/8aGhZQkoFbQ

Az eseményhurok egy folyamat, amely arra vár, hogy a Call Stack megtisztuljon, mielőtt a visszahívásokat a Feladat várólistából a Call Stackbe továbbítja. Amint a Verem tiszta, az eseményhurok elindítja és ellenőrzi a Feladat várólistáját a rendelkezésre álló visszahívások szempontjából. Ha van ilyen, akkor azt a Híváskötegbe tolja, várja meg, amíg a Hívásköteg újra megtisztul, és megismétli ugyanazt a folyamatot.

Forrás – https://www.quora.com/How-does-an-event-loop-work/answer/Timothy-Maxwell

A fenti ábra bemutatja az alapvető munkafolyamatot az eseményhurok és a feladatlista között.

Következtetés

Bár ez egy nagyon alapvető bevezetés, az aszinkron programozás koncepciója a JavaScripten elegendő betekintést nyújt ahhoz, hogy egyértelműen megértse, mi folyik a motorháztető alatt, és hogyan képes a JavaScript egyidejűleg és aszinkron módon futni egyetlen szálaval.

A JavaScript mindig igényelhető, és ha kíváncsi van a tanulásra, azt javaslom, hogy nézd meg ezt Udemy tanfolyam.

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map