Skip to content
Kezdőlap » Promise versus Async/Await

Promise versus Async/Await

Promise vs AsyncAwait
Forrás: https://www.hardwoodandhollywood.com/pop-culture-spin/2015/11/27/win-clubber-lang-vs-ivan-drago/

Akkor beszélünk promise-ról, amikor egy olyan műveletet hajtunk végre, ami nem azonnal ér véget. Nem azonnal produkál eredményt. Bővebben…

Példa a való életből

Ha üres üzemanyag tartállyal áthajtok egy benzinkúton, akkor nem lesz tőle tele a tankom. Ehelyett szépen oda kell állnom valamelyik töltőállomás mellé, adott esetben ki kell várnom a soromat is. De, ha nincs előttem senki sem, akkor is időbe telik, míg megtankolom a kocsit.

Tehát nem azonnal lesz tele a tank. Az eredmény pedig részemről lehet siker, ha véletlenül találok 95 prémium benzint és azzal tudom megitatni a „lovat”. Vagy lehet akár kudarc is (error), ha azon mérgelődöm, hogy sima E10 van a kúton, vagy esetleg ki van írva, hogy nincs benya :). Vagy, ami még rosszabb, hogy otthon felejtem a forgalmit, és akkor ugrik a hatósági árkedvezmény.

Példa a programozás világából

Az szintén egy promise-t eredményez, amikor mondjuk a Firebase authentikációját használom arra, hogy egy felhasználót beléptessek. Mivel az interneten zajlik az egész, időbe telik míg elmegy a kérés a Firebase felé, illetve onnan megjön a válasz.

Tehát már értjük, hogy mi az a promise. A következőben azt szeretném megmutatni, hogyan tudunk egy promise-t átírni az ugyanazt csináló, de szerintem áttekinthetőbb async/await formára.

A konkrét feladat

Az előbb említett példán mennék tovább. Egy felhasználót akarunk beléptetni email címmel és jelszóval. Ezért meghívjuk a Firebase signInWithEmailAndPassword függvényét. Az most mindegy, hogy emögött milyen logika áll. A függvénynek át kell adni egy auth paramétert, ami most szintén mindegy, hogy mit csinál. Továbbá egy email címet és jelszót. (Ezeket adja meg a felhasználó a felületről.)

A signInWithEmailAndPassword egy promise-t ad vissza. Na, de nézzük a kódot először a promise feldolgozásával, ahogyan async/await előtt csináltuk (és persze csinálhatjuk most is):

signInWithEmailAndPassword(auth, email, password)
      .then((userCredential) => {
        // sikeres belépés
        const user = userCredential.user;
        console.log(user);
      })
      .catch((error) => {
        // valami hiba
        const errorCode = error.code;
        const errorMessage = error.message;
        console.log(error.message);
      });

A promise-nek meghívjuk a .then() metódusát, aminek a paramétere egy nyílfüggvény. Ez a nyílfüggvény megkap egy userCredential nevű paramétert, amiben a promise visszaadja nekünk a felhasználó azonosításával kapcsolatos objektumot. Ebből ki tudjuk bányászni a user objektumot, ami a felhasználót tartalmazza, sok-sok tulajdonsággal. Tehát a .then()-el oldottuk fel a promise-t.

Én az egyszerűség kedvéért, csak annyit csináltam, hogy sikeres lekérés esetén kiírattam a konzolba a user objektumot.

A hibakezelés részét a promise .catch() metódusával intézzük. Ez szintén egy nyílfüggvény paramétert kap. Ennek a nyílfüggvénynek egy error objektum az inputja. A törzsében pedig ezt az errort dobtam szét hibakódra és hibaüzenetre és ki is írtam. (Ezt úgy lehet tesztelni, hogy hibás email címet és/vagy jelszót adunk meg a felületről.)

Hogyan néz ki mindez async/await formában?

async function signIn() {
	try {
		const userCredential = await signInWithEmailAndPassword(auth, email, password);
		const user = userCredential.user;
                console.log(user);
	} catch (error) {
	    const errorCode = error.code;
        const errorMessage = error.message;
        console.log(error.message);
	}	
}

Először is az egészet beletettem egy függvénybe (signIn). Ez azért is fontos, mert az await csak egy olyan függvényen belül működik, aminek a definícióját az async kulcsszó előzi meg.

Létrehoztam tehát a signIn nevű függvényt, aminek a hasában a promise-t eltároltam egy userCredential nevű változóban. Ha ezt kiíratnám a konzolba, akkor magát a promise objektumot kapnám meg. Ettől még nem lennénk túl boldogak.

Ezért a nagyon-nagyon fontos dolog, hogy a signInWithEmailAndPassword függvény hívás elé tettem be az await kulcsszót. Ez az a függvény vagy metódus, ami aszinkron módon működik.

Egy függvény általában undefined értékkel tér vissza, ha nincsen return utasítás. De azzal, hogy a signIn függvény definíciója elé betettem az async-et, a belsejében pedig az await-et, a függvény már egy promise-t ad vissza.

A csodát pedig az await csinálja. Ugyanis ez fel is oldja (vagy, ha úgy tetszik feldolgozza) a promise-t és egyből az értéket kapjuk vissza, akárcsak a .then()-el.

Persze a hibát itt is célszerű kezelni. Ezt egy try-catch szerkezettel oldottam meg.

Az async/await átalakítás haszna

Az async/await átalakítás igazi előnye abban mutatkozik meg, hogy ha egy promise-on belül egy másik promise-t kapunk vissza, akkor azt szintén egy újabb .then()-el kellene feloldani. Tehát a végén kapnánk egy .then() után láncolt újabb .then()-t. Nem szép látvány az ilyen :).

Az await-tel viszont azonnal az eredményt kapjuk vissza, még ha az is egy promise. De sokkal áttekinthetőbb kódot eredményez.