Programarea asincronă: tipuri, clasificare, principii de programare, concept, semnificație și aplicare

Programarea asincronă (AP) este o formă de programare paralelă care permite ca o unitate structurală a sistemului să ruleze separat de firul principal al aplicației. Atunci când o sarcină este finalizată, notifică firul principal dacă sarcina a fost finalizată sau nu. O astfel de programare este benefică pentru că mărește lățimea de bandă suportată, ceea ce o face atractivă, având în vedere nevoia tot mai mare a Internetului de sisteme foarte scalabile.

Modele de programare asincronă

Pentru a gestiona continuitatea rezultatului operațiilor neblocante după terminarea lor, au fost create diferite modele AC. Avantajele lor sunt evaluate în funcție de cât de mult se apropie de o schemă secvențială.

Modele de programare asincronă

Tipuri de modele AP:

  1. Modelul pașilor de continuitate - modelul pașilor succesivi. Aceasta este cea mai utilizată asincronie în Node JS. Fiecare funcție primește informații despre modul în care trebuie să trateze rezultatul succesului sau eșecului operațiunii.
  2. Modelul de evenimente - modelul de evenimente, utilizează o arhitectură bazată pe evenimente care permite operațiilor care nu sunt blocante să raporteze terminarea lor prin semne de succes sau eșec, necesită corelare pentru sincronizare.
  3. Promise model - Modelul Promise, explicat prin valorile de returnare ale operațiilor care nu blochează, indiferent de momentul în care au fost primite valorile de succes sau eșec specificate.
  4. Model de generator - Model de generator. Generatoarele sunt folosite pentru a returna temporar controlul către programul apelant și apoi pentru a reveni la subprogram, prin restabilirea stării în punctul în care a fost terminat.

Principii arhitecturale ale nodurilor

Deși Node JS a primit recent unele critici dure pentru utilizarea buclelor de calcul din cauza mediului său cu un singur fir, filosofia sa, bazată pe trei principii arhitecturale puternice, rămâne în cerere.

JavaScript este de natură asincronă, la fel ca Node. Platforma pentru rulați JavaScript pe server, Node.js a fost introdus în 2009, folosind un model de I/O asincron bazat pe evenimente, ceea ce îl face eficient și scalabil.

Chat-ul este cel mai tipic exemplu de aplicație multi-utilizator Node.js în timp real. Începând cu IRC pentru multe protocoale proprietare și deschise pe porturi non-standard, a devenit posibil să se implementeze totul în Noje modern.js cu WebSockets care rulează în mod implicit pe același port 80 care ascultă mesajele noi trimise de clienții lor. Pe partea de client există o pagină HTML cu mai mulți gestionari configurați, unul pentru butonul "Send" care selectează mesajul și îl trimite la WebSocket, și altul care ascultă mesajele care vin la client. Evident, acesta este un model simplu și de bază, dar bazat pe o altă variantă de complexitate.

Modelul inactiv pe care Node JS îl folosește în API pentru a susține programarea asincronă este pasul de continuare. Fiecare operațiune care nu este blocantă primește ca ultim parametru o funcție care include logica de continuare. Acesta va fi apelat după finalizarea operațiunii, atât pentru a procesa rezultatele în caz de succes, cât și pentru a corecta erorile. Funcția "continue" vă permite să indicați unei operații în bloc cum trebuie să continue după încheierea operației.

Principii arhitecturale ale nodurilor

Controlul secvențial al fluxului

Pentru a continua în cadrul acestui model să se stabilească fire succesive de execuție, este necesar să se înlănțuiască fiecare funcție succesivă ca o continuare a celei precedente, unde rezultatele vor fi tratate în caz de succes sau eșec. Acest lucru duce la diagonalizarea codului, care a fost supranumită piramida iadului (callback hell), din cauza lipsei de manevrabilitate practică, atâta timp cât numărul de lanțuri secvențiale crește minim.

Controlul secvențial al fluxului

Paralelizarea - execuția asincronă a operațiilor non-blocate are loc imediat, deoarece simplul său apel este executat în fundal prin definiție. Pentru a transforma operațiunile de blocare în operațiuni de neblocare, este nevoie de un mic proces de încapsulare care să ruleze operațiunea în fundal.

Executarea asincronă a operațiilor care nu blochează

Sincronizarea funcțiilor de continuare

Este nevoie de un lanț la sfârșitul fiecărei secvențe paralele de funcții de terminare care aplică o anumită logică numai după ce, de îndată ce se confirmă că toate ramurile paralele sunt finalizate. Diagramele bazate pe contoare sunt folosite pentru a implementa această verificare.

Sincronizarea funcțiilor de continuare

Exemplu cu continuatori:

  1. Paralelism, bucla permite ca toate perechile de citire-contorizare să fie executate în mod ne-blocant.
  2. secvența, fiecare pereche citită este citită printr-un pas al funcției de continuare.
  3. Sincronizare, fiecare ramură paralelă primește o ultimă continuare, care execută logica de terminare imediat ce toate ramurile au fost finalizate.

Biblioteci de continuitate

Există multe biblioteci care vă pot ajuta simplificați-vă viața pentru dezvoltatorii care lucrează cu modelul AP. Unele dintre acestea nu sunt legate doar de PA, ci și de paradigma funcțională, ceea ce se datorează faptului că mecanismele de implementare a legăturilor sunt în esență beneficii funcționale.

Tipuri de biblioteci:

  1. Async este probabil cea mai cunoscută și cea mai utilizată bibliotecă pentru programarea asincronă bazată pe continuare. Oferă diverse metode de control al fluxului pentru funcțiile care nu blochează.
  2. Join - este o implementare a unei metode de sincronizare care poate fi găsită în alte limbaje, cum ar fi C, și care funcționează cu fire de execuție. Aceasta poate fi utilizată și în promisiuni, deși în acest caz utilizarea sa este mai puțin relevantă.
  3. Fn.js este o bibliotecă excelentă care implementează diverse metode de control funcțional. Aplicabilitatea sa practică în acest context provine din posibilitățile pe care le oferă pentru generarea de funcții neblocante și aplicarea verificării.

Avantaje și dezavantaje

Programarea asincronă bazată pe continuare este o opțiune bună pentru situațiile cu o logică simplă de control al fluxului. Aceasta se referă, de obicei, la programele din Node JS care vă permit să definiți un răspuns fără blocaj la cererile primite.

Avantajele modelului:

  1. Modele simple de cerere și răspuns.
  2. Coerența cu schemele de programare funcțională.
  3. Ușor de înțeles ca mecanism conceptual.

Dezavantaje:

  1. Atunci când logica de control nu este suficient de dezvoltată, procesul devine mai complex, rezultând un cod cu o logică funcțională distribuită care este dificil de citit, înțeles și întreținut.
  2. Dificultate în definirea logicii de control al fluxului.
  3. Mecanisme de sincronizare sofisticate și personalizabile.
  4. Logica de control este distribuită la fiecare ramură ne-blocantă.

Model condus de evenimente

Un eveniment este un semnal în ecosistemul de afaceri. Din punct de vedere anatomic, acestea constau, de obicei, dintr-un tip, un timestamp și un set de date care descriu contextul în care a avut loc evenimentul. Arhitectura de evenimente (EDA) oferă un mecanism de comunicare între clienți și furnizori într-o relație 1:N și cu decuplare nominală. Una dintre numeroasele sale aplicații este de a depana problemele de procesare asincronă a datelor.

În arhitecturile centralizate bazate pe evenimente, există o magistrală centrală de comunicare de mediere, care este responsabilă pentru asigurarea unui proces eficient de înregistrare a clienților care ascultă și de declanșare a notificărilor la cerere către aceștia. Acest mecanism permite o capacitate N:N, iar schema se numește un model PUB/SUB.

În arhitecturile distribuite bazate pe evenimente, fiecare furnizor este responsabil pentru gestionarea abonamentelor clienților săi și pentru trimiterea de notificări atunci când apare un eveniment. Mecanismul de comunicare este, de asemenea, nominal separat, dar, de obicei, numărul furnizorilor și al clienților este de 1:N. Acest model corespunde modelului observat sau surselor de evenimente în jargonul Node JS.

Abstractizare computațională: Promisiune

Abstractizare computațională: Promisiune

O promisiune este o abstracție computațională care reprezintă un angajament din partea unei operații non-blocate apelate de a livra un răspuns programului apelant atunci când rezultatul este primit după finalizare. Promise este un obiect care oferă două metode pentru a activa logica de procesare în caz de succes sau eșec.

Ele răspund unui ciclu de viață simplu care trebuie cunoscut pentru a putea lucra cu ele. Valoarea esențială a promisiunii constă în două principii. În primul rând, logica de proces în caz de succes sau eșec se aplică o singură dată. Și în al doilea rând, logica succesului sau eșecului este garantată, chiar dacă promisiunea este rezolvată înainte de, cum va Șoferii săi au fost introduși. Dacă este necesar, promisiunea își așteaptă gestionarii, în mod asincron Programare JavaScript.

Există în mai multe moduri obțineți promisiuni care pot fi identificate ca modele de construcție care apar periodic atunci când se utilizează acest model. Definiția ES6 include promisiuni și Node JS versiunea 0.12 are suport pentru această specificație. În plus, există mai multe biblioteci care implementează modelul promisiunilor. Pentru a avea un cadru de referință comparativ, a fost definit standardul Promises A+, care gestionează toate implementările cu ajutorul standardelor disponibile la acel moment.

Programarea sincronă și asincronă

Se recomandă să utilizați AP JavaScript, încărcând pentru toate etichetele sale și codul furnizorului de la acesta. Acest lucru oferă cea mai bună compatibilitate cu cel mai mare număr de furnizori. Această plasare oferă tuturor etichetelor furnizorului cea mai mare oportunitate de a finaliza urmărirea înainte ca vizitatorul să treacă la pagina următoare.

Încărcarea sincronă are loc atunci când browserul trebuie să oprească redarea paginii pentru a finaliza execuția codului JavaScript. Dacă detectează o etichetă JS sincronă, blochează afișarea paginii până când codul este complet. Acest lucru este analog cu un camion care se deplasează încet pe un drum cu o singură bandă și care încetinește traficul din spatele său. Site-urile moderne au renunțat la această metodă deoarece prezintă un risc direct de întârziere a timpului de încărcare a paginii.

Dezavantajul acestei metode este că întregul site este blocat de la pornire până când eticheta este complet încărcată. În timp ce furnizorii de etichete au încheiat acorduri de nivel de servicii pe durata livrării lor, mai mulți factori pot afecta performanța. Printre acestea se numără timpii de răspuns lenți asociați cu furnizorii, menținerea unor servere de aplicații inutile într-un model hibrid client-server și traficul lent pe internet. În cazul în care utilizatorul încarcă etichetele în mod sincron, se recomandă să se asigure că furnizorul are un timp de răspuns de 100 milisecunde (ms) sau mai rapid.

API-urile de programare sincronă și asincronă sunt interfețe de programare a aplicațiilor care returnează date pentru solicitări fie imediat, fie, respectiv, mai târziu. API-urile sincrone și asincrone oferă o modalitate de a face cereri imediate sau programate pentru resurse, date sau servicii atunci când acestea sunt disponibile. Metoda modernă, adoptată pentru site-urile web este încărcarea asincronă a etichetelor.

În această metodă, codul JavaScript este procesat în paralel cu restul conținutului paginii. Acest lucru înseamnă că, chiar dacă o etichetă de furnizor răspunde sau se încarcă greu, aceasta nu va încetini restul paginii. Folosind această abordare, nu numai că puteți separa etichetele JavaScript care sunt încărcate independent, dar metoda asincronă minimizează impactul încărcării fișierelor JS externe asupra procesului de redare a paginii.

Înțelegerea și profilarea C #

Înțelegerea și profilarea C #

Microsoft și comunitatea .NET au simplificat foarte mult ASP-urile prin implementarea așteptării asincrone în C #. Ultimele versiuni ASP.NET îl folosește în mod activ pentru a îmbunătăți performanța. Multe instrumente de monitorizare și profilare a performanței încearcă să mențină și să vizualizeze performanța programării asincrone 1C. Produse Stackify Prefix & Retrace are un suport excelent pentru aplicațiile care folosesc C # async await. În primul rând, trebuie să înțelegem cum funcționează de fapt codul care folosește async awai" și HttpClient ca exemplu.

Înțelegerea și profilarea C #

Folosind ILSpy, puteți vedea cum compilatorul convertește acest cod într-o mașină AsyncState Machine. Mașina cu stări finite execută tot codul complex sub acoperire, permițând dezvoltatorilor să scrie cod asincron.

HttpClient ca exemplu

Profilarea programării asincrone în C 5 0 este dificilă, deoarece traversează firele de execuție. În mod tradițional, o metodă și toate apelurile la metodele sale inferioare au loc într-un singur fir. Acest lucru face mai ușor de înțeles relația dintre metodele părinte și copil. Cu codul asincron, este o altă poveste. Metoda părinte se execută într-un singur fir de execuție. Când începe o operațiune de I/O, codul din acel fir se termină. Când o operațiune de I/O se încheie, aceasta continuă să se execute într-un nou fir de execuție. Legătura de cod între aceste fire ca parte a unei tranzacții mai mari este dificilă.

AIOHTTP: server-client pentru asyncio

Aiohttp - permite utilizatorilor să creeze servere și clienți asincroni. Pachetul de programare asincronă aiohttp funcționează atât pentru clientul Web, cât și pentru socket-urile din partea serverului. Documentația din acest exemplu aiohttp este folosită pentru a captura o pagină HTML.

AIOHTTP: client-server pentru asyncio

Acest exemplu arată cum să descărcați unul sau mai multe fișiere, dar puteți descărca și fișiere prin. Acesta specifică mai multe elemente noi, cum ar fi asynctimeout. Aceasta creează un manager de context de timp de așteptare. Codul de mai jos creează o buclă de sincronizare asincronă și o folosește ca funcția principală.

Creați un obiect Sesiune de client în funcția principală de programare asincronă și o funcție de coprogramare care colectează URL-ul a tot ceea ce este, la descărcați. În corutina de descărcare se creează un manager de context care rulează timp de aproximativ X secunde. După acest număr de X secunde, managerul de context se încheie. În continuare, se utilizează funcția get () a sesiunii, care găsește obiectul de răspuns.

Atunci când dezvoltatorul creează atributul content al obiectului de răspuns, acesta returnează aiohttp. StreamReader, care permite utilizatorului să descarce un fișier de orice dimensiune. De îndată ce fișierul este citit, acesta este scris pe discul local. Apoi, utilizați funcția response () pentru a finaliza procesarea răspunsului. Conform documentației, se apelează implicit release (). Cu toate acestea, programarea Python asincronă este în mod clar mai bună. Cel mai bine este să păstrați această funcție pentru a preveni alte probleme. Există o secțiune care blochează o secțiune de cod care este scrisă pe disc, în timp ce codul rămâne blocat. Utilizarea aiohttp - mod real Îmbunătățirea fluxului de lucru, în care utilizatorii nu trebuie să petreacă timp pentru a crea un server, a încărca link-uri și a scrie fișiere asincrone, ceea ce reduce timpul de creare a proiectelor.

Programarea asincronă realizează o mai mare eficiență în software, deoarece nu există blocarea fluxului de execuție pentru procese lungi sau interacțiunea cu utilizatorul, atât pentru dezvoltarea de aplicații Node, cât și pentru aplicații de browser.

Articole pe această temă