Wprowadzenie do Promise w JavaScript
Wiesz już, że użycie modelu asynchroniczności z callbackami łatwo prowadzi do sytuacji callback hell. Dlatego w JavaScript wprowadzono nowy model o nazwie obietnice (promise). Przeanalizujmy ten model.
Obietnica reprezentuje obiekt, do którego parametrem przekazywana jest funkcja, wewnątrz której należy umieszczać nasz asynchroniczny kod:
let promise = new Promise(function() {
// kod asynchroniczny
});
Jak widzisz, zapisałem obiekt z obietnicą
w zmiennej promise. W innym
miejscu kodu mogę zastosować do tej zmiennej
metodę then, przekazując do niej funkcję
z kodem, który ma zostać wykonany po
zakończeniu asynchronicznego kodu, napisanego
podczas tworzenia tej obietnicy:
promise.then(function() {
// wykona się po zakończeniu asynchronicznego kodu
});
Brzmi to skomplikowanie, dlatego spójrzmy na przykład. Załóżmy, że mam taki asynchroniczny kod:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
Załóżmy, że chcę rozwiązać dla niego nasze główne
zadanie asynchroniczności: wykonać pewien
kod po uruchomieniu timera. Jednocześnie
nie chcę umieszczać tego kodu w samym timerze
i chcę, aby do tego kodu w jakiś sposób trafił wynik,
przeze mnie zapisany w zmiennej result.
Ogólnie rzecz biorąc, rozwiązywaliśmy to zadanie w poprzednich
lekcjach za pomocą callbacków i subskrypcji. Spójrzmy
teraz, jak to zrobić za pomocą obietnic.
Na początku należy opakować nasz asynchroniczny kod w obietnicę:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
To jednak nie wystarcza. Musimy w sposób jawny wskazać, że nasz asynchroniczny kod został zakończony. Pomocna nam w tym będzie specjalna funkcja zakończenia, automatycznie trafiająca do pierwszego parametru funkcji, jeśli jest określony:
let promise = new Promise(function(resolve) { // wskazujemy parametr
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Za pomocą funkcji zakończenia możemy w sposób jawny wskazać obietnicy, że asynchroniczny kod się zakończył. Aby to zrobić, musimy wywołać tę funkcję w odpowiednim dla nas miejscu:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // kończymy obietnicę
}, 3000);
});
Jednocześnie, jeśli chcemy przekazać na zewnątrz jakiś wynik asynchronicznego kodu, możemy przekazać go parametrem naszej funkcji zakończenia:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // przekazujemy wynik
}, 3000);
});
Można oczywiście pozbyć się zmiennej pośredniej:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
Teraz w dowolnym innym miejscu możemy wywołać
metodę then naszej obietnicy:
promise.then(function() {
// zadziała po zakończeniu obietnicy
});
Wynik działania obietnicy trafi do pierwszego parametru funkcji, jeśli zechcemy go wskazać:
promise.then(function(result) {
console.log(result); // wypisze tablicę z wynikiem
});
Stwórz obietnicę, wewnątrz której będzie opóźnienie
5 sekund, po którym obietnica powinna
się wykonać, zwracając jako swój wynik jakiś
tekst. Wyświetl ten tekst na ekranie.