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:

javascriptlet 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:

javascriptpromise.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:

javascriptsetTimeout(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ę:

javascriptlet 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:

javascriptlet 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:

javascriptlet 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:

javascriptlet 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:

javascriptlet 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:

javascriptpromise.then(function() {
  // zadziała po zakończeniu obietnicy
});

Wynik działania obietnicy trafi do pierwszego parametru funkcji, jeśli zechcemy go wskazać:

javascriptpromise.then(function(result) {
  console.log(result); // wypisze tablicę z wynikiem
});
Задание 1

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.