bucla de evenimente în nodul js

Bucla De Evenimente In Nodul Js



Node.js este un cadru Javascript puternic care permite utilizatorilor să ruleze cod Javascript pe server în afara browserului. Este un mediu de rulare non-blocant, bazat pe evenimente, pentru construirea de aplicații web scalabile și fiabile. Bucla de evenimente este o parte importantă a Node.js care vă permite să faceți sarcini fără a aștepta ca una să se termine înainte de a începe alta.

Deși Javascript este un limbaj cu un singur thread, Node.js poate atribui sarcini sistemului de operare, permițându-i să proceseze mai multe sarcini în același timp. Mai multe sarcini trebuie finalizate în același timp, deoarece operațiunile din sistemul de operare sunt multi-threaded. Callback-ul asociat fiecărei operații este adăugat la coada de evenimente și este programat de Node.js să ruleze când sarcina specificată este finalizată.

Pentru a scrie cod Node.js eficient și de încredere, utilizatorul trebuie să aibă o înțelegere solidă a buclelor de evenimente. De asemenea, poate ajuta la depanarea eficientă a problemelor de performanță. Bucla de evenimente din Node.js economisește memorie și vă permite să faceți mai multe lucruri simultan, fără a fi nevoie să așteptați ca fiecare să se termine. Termenul „asincron” se referă la orice funcție Javascript care rulează în fundal fără a bloca cererile primite.







Înainte de a trece direct la buclele de evenimente, să aruncăm o privire asupra diferitelor aspecte ale limbajului de programare Javascript.



Javascript ca limbaj de programare asincron

Să aruncăm o privire asupra conceptelor de programare asincronă. Javascript este folosit în aplicații web, mobile și desktop, dar trebuie remarcat faptul că Javascript este un limbaj de programare sincron, cu un singur fir.



Este dat un exemplu de cod simplu pentru a înțelege conceptul.





metoda funcției 1 ( ) {

consolă. Buturuga ( „Funcția 1” )

}

metoda funcției 2 ( ) {

consolă. Buturuga ( „Funcția 2” )

}

metoda 1 ( )

metoda 2 ( )

În acest cod, sunt create două funcții simple și metoda 1 este apelată mai întâi, astfel încât să înregistreze mai întâi metoda 1 și apoi să se mute la următoarea.

Ieșire



Javascript ca limbaj de programare sincron

Javascript este un limbaj de programare sincron și execută fiecare linie pas cu pas, deplasându-se de sus în jos cu o singură linie executată la un moment dat. În exemplul de cod dat mai sus, metoda1 este înregistrată mai întâi în terminal și apoi metoda2.

Javascript ca limbaj de blocare

Fiind un limbaj sincron javascript are o funcționalitate de blocare. Nu contează cât de mult durează pentru a finaliza un proces în desfășurare, dar un nou proces nu va fi început până când cel anterior nu va fi finalizat. În exemplul de cod de mai sus să presupunem că există o mulțime de scripturi de cod în metoda 1, indiferent de cât timp durează fie 10 secunde, fie un minut, metoda 2 nu va fi executată până când tot codul din metoda 1 nu va fi executat.

Este posibil ca utilizatorii să fi experimentat acest lucru în timpul navigării. Când o aplicație web se execută într-un browser în back-end, se execută o bucată uriașă de cod, astfel încât browserul pare să fie înghețat pentru ceva timp înainte de a returna accesul de control la utilizator. Acest comportament este cunoscut sub numele de blocare. Browserul nu poate primi alte solicitări până când cererea curentă nu a fost procesată.

Javascript este un limbaj cu un singur thread

Pentru a rula un program în javascript este folosită funcționalitatea thread-ului. Threadurile sunt capabile să îndeplinească doar o sarcină la un moment dat. Alte limbaje de programare acceptă multi-threading și pot rula mai multe sarcini în paralel, javascript conține doar un fir pentru executarea oricărui script de cod.

În așteptare în Javascript

După cum reiese din numele din această secțiune, trebuie să așteptăm ca cererea noastră să fie procesată pentru a continua. Așteptarea poate dura câteva minute, timp în care nu mai este primită nicio cerere. Dacă scriptul de cod continuă fără a aștepta, atunci codul va întâmpina o eroare. Unele funcționalități urmează să fie implementate în Javascript sau mai precis în Node.js pentru a face codul asincron.

Acum că am înțeles diferitele aspecte ale Javascript, să înțelegem sincronul și asincronul prin câteva exemple simple.

Execuția sincronă a codului în Javascript

Sincron înseamnă că codul este executat secvenţial sau mai simplu pas cu pas, pornind de sus şi deplasându-se în jos linie cu linie.

Mai jos este dat un exemplu care poate ajuta la înțelegere:

// application.js

consolă. Buturuga ( 'Unu' )

consolă. Buturuga ( 'Două' )

consolă. Buturuga ( 'Trei' )

În acest cod, există trei instrucțiuni console.log, fiecare tipărind ceva. În primul rând, prima declarație care va tipări „Unul” în consolă este trimisă în stiva de apeluri pentru 1 ms (estimat), apoi este înregistrată la terminal. După aceea, a doua instrucțiune este împinsă în stiva de apeluri și acum timpul este de 2 ms cu una adăugată din cea anterioară și apoi înregistrează „Două” în consolă. În cele din urmă, ultima declarație este împinsă în stiva de apeluri pentru moment, timpul este de 3 ms și înregistrează „Trei” în consolă.

Codul de mai sus poate fi executat prin invocarea următoarei comenzi:

aplicație nod. js

Ieșire

Funcționarea este explicată mai sus în detaliu și, ținând-o în considerare, ieșirea este conectată în consolă cât ai clipi:

Execuția asincronă a codului în Javascript

Acum să refactorăm același cod introducând apeluri inverse și făcând codul asincron. Codul de mai sus poate fi refactorizat ca:

// application.js
funcția printOne ( sună din nou ) {
setTimeout ( funcţie ( ) {
consolă. Buturuga ( 'Unu' ) ;
sună din nou ( ) ;
} , 1000 ) ;
}
funcția printTwo ( sună din nou ) {
setTimeout ( funcţie ( ) {
consolă. Buturuga ( 'Două' ) ;
sună din nou ( ) ;
} , 2000 ) ;
}
funcția printThree ( ) {
setTimeout ( funcţie ( ) {
consolă. Buturuga ( 'Trei' ) ;
} , 3000 ) ;
}
consolă. Buturuga ( „Începutul programului” ) ;
printOne ( funcţie ( ) {
printDoi ( funcţie ( ) {
printTrei ( ) ;
} ) ;
} ) ;
consolă. Buturuga ( „Sfârșitul programului” ) ;

În acest cod de mai sus:

  • Trei funcții sunt declarate pentru a tipări „Unul”, „Doi” și „Trei”, fiecare funcție are un parametru de apel invers care permite execuția secvențială a codului.
  • Un timeout este setat folosind funcția setTimeout și există o instrucțiune console.log pentru imprimare după o anumită întârziere.
  • Sunt tipărite două mesaje „Start of the Program” și „End of the Program” care indică începutul și sfârșitul programului.
  • Programul începe prin tipărirea „Start of the Program” după care funcția printOne este executată cu o întârziere de 1 secundă, apoi funcția printTwo este executată cu o întârziere de 2 secunde, iar în final funcția printThree este executată cu o întârziere de 3 secunde. întârziere.
  • Programul nu așteaptă execuțiile de cod asincron în cadrul funcțiilor setTimeouts, care înregistrează instrucțiunea „Sfârșitul programului” înainte de a imprima One, Two și Three.

Ieșire

Rulați codul de mai sus executând această comandă în terminal:

aplicație nod. js

Acum ieșirea din terminal va apărea asincron ca:

Acum că avem o înțelegere completă a execuției sincrone și asincrone, să trecem la consolidarea conceptului nostru de buclă de evenimente în Node.js.

Node.js: Mecanism de buclă de evenimente

Execuția atât a sarcinilor sincrone, cât și a celor asincrone este gestionată de bucla de evenimente din Node.js. Execuția este invocată de îndată ce proiectul Node.js este lansat și transferă fără probleme sarcinile complexe în sistem. Acest lucru asigură că alte sarcini pot rula fără probleme pe firul principal.

Explicația vizuală a buclei de evenimente în Node.js

Bucla de evenimente este continuă și semi-infinită în Node.js. Bucla de evenimente este invocată de pornirea scriptului de cod Node.js și este responsabilă pentru efectuarea de apeluri API asincrone și apelarea proceselor. Tick(), iar programarea temporizatoarelor, apoi reia execuția buclei de eveniment.

În Node.js, cinci tipuri principale de cozi gestionează apelurile inverse:

  • „Coada de cronometru” cunoscută în mod obișnuit ca min-heap este responsabilă pentru gestionarea apelurilor inverse asociate cu „setTimeout” și „setInterval”.
  • Apelurile inverse pentru operațiuni asincrone, cum ar fi modulele „fs” și „http” sunt gestionate de „I/O Queue”.
  • „Coada de verificare” conține apeluri inverse pentru funcția „setImmediate”, care este unică pentru Node.
  • „Coada de închidere” gestionează apelurile inverse asociate cu orice eveniment de închidere a activității asincrone.
  • În cele din urmă, există două cozi diferite în coada „Micro Sarcină”:
    • Coada „nextTick” conține apeluri inverse asociate cu funcția „process.nextTick”.
    • Coada „Promise” controlează apelurile inverse legate de Promisia nativă.

Funcționalitatea Buclă de evenimente în Node.js

Bucla de evenimente funcționează conform cerințelor specifice care controlează ordinea de execuție a apelului invers. Codul Javascript sincron al utilizatorului primește prioritate la începutul procesului, astfel încât bucla de evenimente începe doar atunci când stiva de apeluri este șters. Următoarea secvență de execuție urmează un model structurat:

Cea mai mare prioritate este acordată apelurilor înapoi în coada de microtask, apoi se deplasează pentru a executa sarcinile din coada nextTick urmate de sarcinile din coada Promise. Procesele din apelurile înapoi în coada temporizatorului sunt apoi gestionate, după care coada de microsarcini este re-vizitată după fiecare apel invers al temporizatorului. Callback-urile din cozile de I/O, de verificare și de închidere sunt apoi executate într-un model similar, cu coada de microtask vizitată după fiecare fază.

Bucla continuă să se execute dacă sunt mai multe apeluri de procesat. Când scriptul de cod s-a încheiat sau nu sunt lăsate apeluri inverse de procesat, bucla de evenimente se termină eficient.

Acum că înțelegem profund bucla de evenimente, să ne uităm la caracteristicile acesteia.

Caracteristicile buclei de evenimente în Node.js

Principalele caracteristici sunt:

  • Bucla de evenimente este o buclă infinită și continuă să execute sarcinile de îndată ce le primește și intră în modul de repaus în cazul în care nu există sarcini, dar începe să funcționeze imediat ce sarcina este primită.
  • Sarcinile din coada de evenimente sunt executate numai atunci când stiva este goală înseamnă că nu există nicio operațiune activă.
  • Reapelurile și promisiunile pot fi folosite în bucla de eveniment.
  • Deoarece bucla de evenimente urmează principiul cozii de tip de date abstracte, îndeplinește prima sarcină, apoi trece la următoarea.

După o înțelegere aprofundată a buclei de evenimente și a logicii execuțiilor asincrone și sincrone, înțelegerea diferitelor faze poate solidifica conceptele buclei de evenimente.

Fazele buclei de evenimente Node.js

După cum am menționat mai sus, bucla de evenimente este semi-infinită. Are multe faze, dar unele faze sunt folosite pentru manipularea internă. Aceste faze nu au niciun efect asupra scriptului de cod.

Bucla de evenimente urmează funcționalitatea Queue și execută sarcina pe principiul first-in și first-out. Cronometrele programate vor fi gestionate de sistemul de operare până când expiră. Cronometrele expirate sunt apoi adăugate la coada de apel invers pentru cronometre.

Bucla de evenimente execută sarcinile din coada temporizatorului una câte una până când nu mai sunt sarcini rămase sau atinge numărul maxim permis de sarcini. În secțiunile de mai jos sunt explicate fazele de bază ale buclelor de evenimente.

Faza temporizatoarelor

În Node.js există un timer API care poate programa funcțiile care urmează să fie executate în viitor. După ce timpul alocat a trecut, timer-ul se va executa de îndată ce pot fi programate; cu toate acestea, se poate confrunta cu o întârziere fie de la sfârșitul sistemului de operare, fie din cauza executării altor apeluri.

API-ul cronometrelor are trei funcții principale:

  • setTimeout
  • setImmediate
  • setInterval

Funcțiile menționate mai sus sunt sincrone. Faza temporizatorului din bucla de evenimente are domeniul de aplicare limitat la funcțiile setTimeout și setInterval. În timp ce funcția de verificare se ocupă de funcția setImmediate.

Să luăm în considerare un exemplu simplu pentru a consolida partea teoretică:

// application.js

function delayedFunction ( ) {

consolă. Buturuga ( „funcția întârziată este executată după expirarea timpului” ) ;

}

consolă. Buturuga ( „Începutul programului” ) ;

setTimeout ( delayedFunction, 2000 ) ;

consolă. Buturuga ( „Sfârșitul programului” ) ;

În acest cod:

  • Programul începe prin înregistrarea pe terminal a declarației „Start of the Program”.
  • Apoi delayedFunction este apelată cu un temporizator de 2 ms, script-ul de cod nu se oprește și continuă să gestioneze întârzierea în fundal.
  • Instrucțiunea „Sfârșitul programului este înregistrată după prima declarație.
  • După o întârziere de 2 ms, instrucțiunea din delayedFunction este înregistrată în terminal.

Ieșire

Ieșirea va apărea ca:

Se poate observa că codul nu este oprit pentru procesarea delayedFunction; se deplasează înainte și după întârziere, funcția callback este procesată.

Apeluri în așteptare

Bucla de evenimente verifică evenimentele care au loc, cum ar fi citirea fișierelor, activitățile de rețea sau sarcinile de intrare/ieșire, în faza de sondare. Este important de știut că, în Node.js, doar unele dintre evenimente sunt gestionate în această fază de sondare. Cu toate acestea, în iterația ulterioară a buclei de evenimente, anumite evenimente pot fi amânate la faza în așteptare. Acesta este un concept cheie de reținut atunci când optimizați și depanați codul Node.js care implică operațiuni complexe bazate pe evenimente.

Este important să înțelegeți că în timpul fazei de așteptare a apelurilor inverse, bucla de evenimente adaugă evenimente amânate la coada de apeluri în așteptare și le efectuează. Această fază gestionează, de asemenea, unele erori de socket TCP pe care sistemul le-a generat, cum ar fi evenimentele de eroare ECONNREFUSED pe anumite sisteme de operare.

Mai jos este menționat un exemplu pentru a consolida conceptul:

// application.js
const fs = cere ( „fs” ) ;
funcția readFileAsync ( filePath, apel invers ) {
fs. readFile ( „./PromiseText.txt” , 'utf8' , funcție ( gres, date ) {
dacă ( a greșit ) {
consolă. eroare ( ` Eroare fișier de citire : $ { a greșit. mesaj } ` ) ;
} altfel {
consolă. Buturuga ( ` Fişier conţinut : $ { date } ` ) ;
}
sună din nou ( ) ;
} ) ;
}
consolă. Buturuga ( „Începutul programului” ) ;
readFileAsync ( „./PromiseText.txt” , funcție ( ) {
consolă. Buturuga ( „Fișier citit apel invers executat” ) ;
} ) ;
consolă. Buturuga ( „Sfârșitul programului” ) ;

În acest cod:

  • Programul este inițiat prin înregistrarea declarației „Start of the Program” în terminal.
  • ReadFileAsync este definit asincron pentru a citi conținutul fișierului „PromiseText.txt”. Este o funcție parametrizată care execută o funcție de apel invers după ce fișierul a fost citit.
  • Funcția readFileAsync este apelată pentru a începe procesul de citire a fișierului.
  • În procesul de citire a fișierului, programul nu se oprește; în schimb, trece la următoarea instrucțiune și o conectează în terminalul „Sfârșitul programului”.
  • Evenimentul asincron al citirii fișierului este procesat în fundal de bucla de evenimente.
  • După ce fișierul a fost citit asincron și conținutul a fost înregistrat pe terminal, programul înregistrează conținutul fișierului pe terminal. După aceea, înregistrează următorul mesaj „Fișier citit apel invers executat”.
  • Bucla de evenimente gestionează operațiunile de apel invers în așteptare în faza următoare.

Ieșire

Rezultatul execuției de mai sus este:

Inactiv, Faza de pregătire în Node.js

Faza inactivă este utilizată pentru a se ocupa de funcțiile interne în Node.js, deci nu este o fază standard. Nu influențează scriptul codului. Faza inactiv este ca o perioadă de pauză pentru bucla de evenimente în timpul căreia gestionează sarcinile cu prioritate scăzută în fundal. Un exemplu simplu pentru a înțelege această fază este:

const { inactiv } = cere ( 'idle-gc' ) ;

inactiv. ignora ( ) ;

În acest cod, se folosește modulul „idle-gc” care permite ignorarea fazei inactiv. Acesta servește la gestionarea situațiilor în care bucla de evenimente este ocupată și sarcinile de fundal nu sunt efectuate. Utilizarea idle.ignore nu este considerată optimă, deoarece poate cauza probleme de performanță.

Faza de sondare în Node.js

Faza de sondaj în Node.js servește ca:

  • Se ocupă de evenimentele din coada de sondaje și îndeplinește sarcinile corespunzătoare.
  • Acesta decide cât timp să petreceți așteptând și verificând operațiunile I/O în proces.

Pe măsură ce bucla de evenimente intră în faza de sondare din cauza absenței unui temporizator, una dintre sarcinile de mai jos va fi efectuată:

  • În faza de sondare a buclei de evenimente din Node.js, evenimentele I/O în așteptare sunt puse în coadă și apoi executate într-o procedură secvenţială urmând principiul First In and First Out până când coada devine goală. În timpul execuțiilor de apel invers, cozile nextTick și microtasks sunt de asemenea în acțiune. Acest lucru asigură fluiditatea și permite gestionarea operațiunilor I/O mai eficient și mai fiabil.
  • Dacă coada este goală și scriptul nu a fost programat de funcția setImmediate() atunci bucla de evenimente se va încheia și va trece la următoarea fază (verificare). Pe de altă parte, dacă programarea scriptului a fost făcută de funcția setImmediate(), bucla de evenimente permite ca apelurile să fie adăugate la coada care va fi executată de aceasta.

Acest lucru este cel mai bine ilustrat cu un exemplu de cod simplu:

setTimeout ( ( ) => {

consolă. Buturuga ( „Operațiune de asincronizare finalizată” ) ;

} , 2000 ) ;

consolă. Buturuga ( 'Start' ) ;

setImmediate ( ( ) => {

consolă. Buturuga ( „setImmediate callback executat” ) ;

} ) ;

consolă. Buturuga ( 'Sfârşit' ) ;

În acest cod:

  • Două mesaje „Start” și „End” indică inițierea și terminarea programului.
  • Funcția setTimeout() setează o funcție de apel invers cu o întârziere de 2 ms și înregistrează „Operațiunea asincronă finalizată” la terminal.
  • Funcția setImmediate() înregistrează mesajul „setImmediate callback executat” pe terminal după ce mesajul Start a fost înregistrat pe terminal.

Ieșire

Ieșirea ar arăta mesajele cu doar un minut de observație că „Operațiunea asincronă finalizată” durează și este tipărită după mesajul „Încheierea”:

Faza de verificare Node.js

După ce faza de sondare a fost executată, sunt executate apelurile înapoi în faza de verificare. Dacă un script de cod este programat folosind funcția setImmediate() și funcția de sondare este gratuită, bucla de evenimente funcționează trecând direct la faza de verificare în loc să rămână inactiv. Funcția setImmediate() este un temporizator unic care funcționează în timpul diferitelor faze ale buclei de evenimente.

API-ul libuv este folosit pentru a planifica execuțiile de apel invers după finalizarea execuției fazei de sondare. În timpul execuției codului, bucla de evenimente intră în faza de sondare în care așteaptă cererile de conectare primite. Într-un alt caz, dacă apelul invers este programat utilizând funcția setImmediate() și faza de sondare se încheie fără nicio activitate, se va trece la faza de verificare în loc să aștepte. Luați în considerare exemplul de mai jos pentru înțelegere:

// application.js

consolă. Buturuga ( 'Start' ) ;

setImmediate ( ( ) => {

consolă. Buturuga ( „Reapel imediat” ) ;

} ) ;

consolă. Buturuga ( 'Sfârşit' ) ;

În acest cod sunt conectate trei mesaje la terminal. Funcția setImmediate() trimite apoi un apel invers pentru a înregistra mesajul „ Reapel imediat ” la terminal.

Ieșire

Ieșirea codului de mai sus va apărea în următoarea secvență:

Node.js închide apelurile inverse

Node.js folosește această fază de închidere pentru a rula apeluri inverse pentru a închide evenimente și a încheia o iterație a buclei de evenimente. După ce conexiunea este închisă, bucla de evenimente se ocupă de evenimentele de închidere din această fază. În această fază a buclei de evenimente, „nextTick()” și microtask-urile sunt generate și procesate în mod similar cu alte faze.

Funcția process.exit este utilizată pentru a încheia bucla de evenimente în orice moment. Bucla de evenimente va ignora orice operațiuni asincrone în așteptare și procesul Node.js se va încheia.

Un exemplu simplu de luat în considerare este:

// application.js
const net = cere ( 'net' ) ;
const Server = net. createServer ( ( priză ) => {
priză. pe ( 'închide' , ( ) => {
consolă. Buturuga ( „Priză închisă” ) ;
} ) ;
priză. pe ( 'date' , ( date ) => {
consolă. Buturuga ( „Date primite:” , date. toString ( ) ) ;
} ) ;
} ) ;
Server. pe ( 'închide' , ( ) => {
consolă. Buturuga ( „Server închis” ) ;
} ) ;
const port = 3000 ;
Server. asculta ( port, ( ) => {
consolă. Buturuga ( `Serverul ascultă pe portul $ { port } ` ) ;
} ) ;
setTimeout ( ( ) => {
consolă. Buturuga ( „Se închide serverul după 10 secunde” ) ;
Server. închide ( ) ;
proces. Ieșire ( ) ;
} , 10000 ) ;

În acest cod:

  • const net = require(‘net’) „importă modulul net necesar pentru a gestiona un server TCP și „ const server = net.createServer((socket) => { ” creează o nouă instanță de server TCP.
  • socket.on(‘închide’, () => {… } ” ascultă „închiderea” pe toate prizele. Când conexiunea la priză este închisă, mesajul „Socket Closed” este înregistrat pe terminal.
  • socket.on(‘date’, (date) => {} ” verifică datele primite de la toate prizele individuale și le imprimă folosind funcția „.toString()”.
  • server.on(‘închide’, () => {…} ” verifică evenimentul „închidere” pe serverul însuși, iar când conexiunea la server este închisă, înregistrează mesajul „Server închis” pe terminal.
  • server.listen(port, () => {…} ” ascultă conexiunile de intrare pe port.
  • setTimeout(() => {…} ” setează un temporizator de 10 ms pentru a închide serverul.

Aceasta încheie discuția despre diferitele faze ale buclei de evenimente din Node.js. Înainte de a trece la o concluzie, să discutăm un ultim lucru, care este cum să ieșim din bucla de evenimente în Node.js.

Ieșirea din bucla de evenimente în Node.js

Bucla de evenimente este în faza de execuție atâta timp cât există unele sarcini în toate cozile de faze ale buclei de evenimente. Bucla de evenimente se termină după ce faza de ieșire este emisă și apelul invers de ascultător de ieșire revine dacă nu mai sunt sarcini în cozi.

Modul explicit de a încheia o buclă de eveniment este utilizarea metodei „.exit”. Procesele active ale Node.js se vor încheia instantaneu de îndată ce este apelată funcția process.exit. Toate evenimentele programate și în așteptare vor fi eliminate:

proces. pe ( 'Ieșire' , ( cod ) => {

consolă. Buturuga ( `Ieșire cu codul de ieșire : $ { cod } ` ) ;

} ) ;

proces. Ieșire ( 1 ) ;

Utilizatorii pot asculta funcția .exit. Este de remarcat faptul că funcția „.exit” trebuie să fie sincronă, deoarece programul Node.js se va închide imediat ce va asculta acest eveniment.

Aceasta încheie discuția despre bucla de evenimente. Un articol aprofundat care a acoperit toate conceptele, fazele și exemplele legate de bucla de evenimente.

Concluzie

Înainte de a înțelege bucla de evenimente, o prezentare generală a conceptelor sincrone și asincrone poate ajuta la înțelegerea fluxului de cod în bucla de evenimente. Execuția sincronă înseamnă execuție pas cu pas, în timp ce execuția asincronă înseamnă oprirea unor pași fără a aștepta finalizarea lor. Funcționarea buclei de evenimente împreună cu toate fazele împreună cu exemple adecvate sunt discutate în articol.