Deo zbornika Napredni Javaskript
Obećanja u Javascriptu
Obećanja (promise) su uvedena u Javascript kao alternativa povratnim pozivima. Povratni pozivi nisu adekvatni za upravljanje asinhronim tokom programa, usled previše nivoa gnježdenja (tzv. callback hell).
Kao i povratni pozivi, obećanja se koriste za obradu rezultata asinhrone funkcije. Kao što naziv ukazuje, obećanja mogu biti ispunjena ili odbijena. Obećanja se ponašaju kao čuvari mesta za krajnji rezultat.
Obećanja imaju tri uzajamno isključiva stanja:
- čekanje pre nego što je rezultat spreman.
- ispunjeno kada je rezultat spreman.
- odbijeno ako ima greške.
Upotreba obećanja
Svrha obećanja je da omoguće bolju sintaksu za kontinuirano prosleđivanje (continuation-passing style). Asinhronu funkciju koja prima callback koristimo na sledeći način:
uradiNesto(argument, rezultat => {
// uporebi rezultat
})
Asinhronu funkciju koja vraća obećanje koristimo na sledeći:
uradiNesto(argument)
.then(rezultat => {
// uporebi rezultat
})
Povratna funkcija unutar metoda then()
se poziva kada je rezultat spreman. Zavisno od uspešnosti obećanja, poziva se povratna funkcija prosleđena metodu then()
ili catch()
:
uradiNesto(argument)
.then(rezultat => { /* obećanje ispunjeno */ })
.catch(greska => { /* obećanje odbijeno */ })
Ulančavanje obećanja
Ako bismo hteli da nastavimo asinhronu logiku, morali bismo da ugnjezdimo još jednu povratnu funkciju unutar prethodne.
uradiNesto(argument, rezultat => {
uradiNestoDrugo(rezultat, (err, podatak) => {
// uporebi podatak
})
})
Međutim, obećanja možemo ulančavati, ako povratna funkcija unutar then()
vraća obećanje. Na primer:
uradiNesto(argument)
.then(rezultatA => {
return uradiNestoDrugo(rezultatA)
})
.then(rezultatB => {
// uporebi rezultatB
})
Primer: fetch metoda
fetch('https://randomuser.me/api/?results=10')
.then(response => {
// vraca novo obecanje
return response.json()
})
.then(data => {
// koristimo podatak
data.results.map(user => console.log(user.name.first))
})
.catch(err => console.log(err))
Ako dođe do greške u toku mrežnog poziva, biće izvršena povratna funkcija samo unutar catch()
metode.