Uvod

asyn/await

Korišćenje samo jednog promisa je jasno i jednostavno, medjutim kada se program zakomplikuje asinhronom logikom, rad sa promisima se rapidno otežava. Sa ES2017 standardnom je stigla i nova sintaksa “async/await”, koja olakšava rad sa promisima, i omogućava jednostavnije predstavljanje serije asinhronih promisa. Korišćenje “async/await” sintakse nam omogućava da višestruke medjusobno zavisne asinhrone radnje, prikažemo čitljivije i tako izbegnemo tzv. “promise hell”. Treba napomenuti da se uz async funcije ne mogu koristiti “obične” callback funkcije.

“Async/await” sintaksa ne isključuje promise, nego menja način “konzumacije” promisa. Async/Await sintaksa nam omogućava da pišemo asinhroni kod prema sekvencijalnom redosledu izvršavanja tako da liči na sinhroni kod.

Sintaksa asinhrone funkcije

Obeležavanje funkcije sa “async”

Asinhrona funkcija je funkcija unutar koje se izvršava asinhroni kod. Asinhrona funkcija je obeležena se sa ključnom reči “async”. Tako obeležena funkcija daje do znanja kompajleru da će se unutar nje izvršiti asinhrona operacija.

Taskovi koje async funkcija vrši u pozadini su:

  1. Automatski konvertuje regularnu funkciju u promise
  2. Sve što je vraćeno sa “return” u telu funkcije, nakon uspešne operacije postaje “Promise.resolve”

    Async funkcija uvek vraća “promise”, čak i ako vraćena vrednost nije “promise”. Async funkcija “obavija” svaku vraćenu vrednost i prosledjuje je kao Promise.
  3. Async funkcija omogućava korišćenje await operatora.

“Await” operator

Ovaj operator može da se koristi jedino u okviru “async” funkcije, gde pauzira izvršenje async funkcije. Rezervisana reč “await” pauzira izvršenje async funkcije sve dok ne doobije rezultate operacije tj. dok se ne vrati promise. Ako je Promise u stanju fulfilled, onda je rezulta koji je “dočekao” await ima “fulfillment” vrednost, a ako je dočekani Promise u stanju “rejected” onda await prosledjuje “rejection” vrednost.

Error handling

Uz operator await se koristi standardna try/catch sintaksa. Operator await “čeka” promise, i ukoliko je operacija uspešna, async funkcija prosledjuje “promise resolved”. U slučaju neuspešne operacije, prosledjuje “promise rejected”, dok se za “hvatanje” tog “exception-a” koristi “catch” blok.



Objašnjenje:
Koristeći async/await sintaksu omogućavamo javascritpu da bolje upravlja greškama (naručito stack trace), i da na efikasniji način koristi memoriju (eng. memory-efficient).

Paralelizam

Async operacije se izvršavaju u serijama jedna za drugom, pa ih ne treba mešati sa “Promise.all” gde se promisi izvršavaju paralelno. Za paralelno izvršavanje promisa je najbolje da koristitmo “Promise.all” sintaksu. Treba naglasiti da “async/await” sintaksa ne isključuje “promise.all” sintaksu, čak šta više zajedno daju svoj maksimum a kod je jasan i pregledan. Kroz naredne primere će biti prikazana razlika izmedju seriskog i paralelnog izvršavanja.

Serijsko izvršavanje

Ovo je primer seriskog izvršavanja jer drugi “await” čeka da se izvrši prva operacija.

Paralelno izvršavanje

Ukoliko želimo da se operacije izvršavaju paralelno potrebno je da pustimo da se obe funkcije paralelno izvode, a tek onda da ih “sačekamo” await operatorom:

Simbioza Promise.all i async/await sintaksi

Sa destruktuiranjem možemo da pojedinačno dodelimo vraćene vrednosti:

Iteracija asinhrone operacije

for…of

Preporuka je da se za iteraciju u asinhronoj funkciji koristi “for…of” petlja:

Problemi sa metodama za iteraciju nizova

Metoda za iteraciju kroz nizove, kao što je “forEach()” se ne može koristiti sa async/await sintaksom. Korišćenje “await” operatora unutar metode izbacuje error, a greška nastaje iz razloga što “await” operator može da postoji samo u okviru async funkcije, a u ovom slučaju bi se nalazio u okviru forEach() metode.

Čak i ukoliko bi u okviru forEach() anonimnu callback funkciju definisali kao asinhronu, to bi samo pomoglo da ne izbacuje error, ali to ne bi dalo očekivani rezultat, jer metoda “forEach” ne “čeka” asinhronu operaciju, već nastavlja izvršavanje sinhronog koda.

Primeri primene Async/Await sintakse

U ovoj sekciji je opisan postupak prebacivanja sintakse sa “plain” promise u novu poboljšanu Async/Await sintaksu.

Pojedinačne asihrone operacije

a) Jednostavna asinhrona operacija



b) XMLHttpRequest()

U ovome primeru su prikazani snippeti za dobijanje podataka u vidu JSON-a, na dva načina: prvi koji koristi HMLHttpRequest() i Promise i drugi gde je primenjena nova Async/Await sintaksa.



c) fetch()



Serija sekvencijalnih promisa



Serija sekvencijalnih medusobno zavisnih promisa

Na ovakavom primeru se najbolje vide sve prednosti i poboljšanja koja donosi nova sintaksa. Prvo je prikazana serija povezanih promisa samo sa promisima (bez Async/Await):



Serija višestrukih paralelnih asinhronih operacija



Podelite:

Ostavite komentar