• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

JS - promise

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
0 głosów
329 wizyt
pytanie zadane 6 czerwca 2020 w JavaScript przez lukas_1994 Nowicjusz (150 p.)
zmienione kategorie 6 czerwca 2020 przez draghan

Witam. Czy mógłby mi ktoś wytłumaczyć działanie kodu:

function loadImageAsync(url){
    return new Promise((resolve, reject) => {
        const img=new Image();
        
        img.addEventListener("load", (event) =>{resolve(img)});
        img.addEventListener("error", reason =>reject(new Error(`Failed to load ${url}`))
        
        );
        console.log(img);
        img.src=url;
        console.log(img);
    })
}

const image =loadImageAsync("http://thecatapi.com/api/images/get?format=src&type=jpg&size=small")
.then(img=>document.querySelector('.image').appendChild(img))
.catch(reason=>console.log(reason));

Skąd w addlistenerze w funkcji resolve jest już adres url skoro jest on przypisany niżej?

1 odpowiedź

+1 głos
odpowiedź 6 czerwca 2020 przez ScriptyChris Mędrzec (190,190 p.)
wybrane 7 czerwca 2020 przez lukas_1994
 
Najlepsza

Funkcja loadImageAsync otrzymuje parametr url i zwraca Promise. Callback przekazany do konstruktora Promisa ma dostęp do zmiennej url, poprzez domknięcie.

Co masz na myśli przez "skoro jest on przypisany niżej?"? Najpierw wywoływana jest funkcja loadImageAsync, więc parametr url jest już przekazany do środka zanim kod Promisa zostanie wykonany.

komentarz 6 czerwca 2020 przez lukas_1994 Nowicjusz (150 p.)
Mam chyba problem z zrozumieniem asynchroniczności.

Chodziło mi o to że jest tworzony obiekt pod zmienną img, i jest przekazywany do listenera w callbacku a on ma już adres url, chociaż jest on przypisany niżej. Ale chyba nie mogłem zrozumieć że jest to callback i wykonuje się po przypisaniu do img adresu url.

Jeśli ma ktoś jakieś materiały które pomogą to zrozumieć, poprosiłbym. :)
komentarz 6 czerwca 2020 przez ScriptyChris Mędrzec (190,190 p.)
edycja 6 czerwca 2020 przez ScriptyChris

Chodziło mi o to że jest tworzony obiekt pod zmienną img, i jest przekazywany do listenera w callbacku a on ma już adres url, chociaż jest on przypisany niżej

Zauważ, że to wszystko dzieje się w funkcji loadImageAsync. Żeby kod wewnątrz niej został wykonany, to funkcja musi najpierw zostać wywołana. I to dzieje się najpierw (linia 15). Funkcja docelowo zwraca Promisa, ale najpierw jego konstruktor wykonuje callbacka. W nim tworzona jest zmienna img, a pod nią są podpinane listenery. Potem do konsoli wypisana jest aktualna wartość zmiennej img, podpięty jest src i drugi raz logowana wartość zmiennej img. Dopiero teraz Promise jest zwracany do zmiennej image (linia 15). Funkcje resolve lub reject będą wywołane tylko wtedy, gdy wystąpi zdarzenie load lub error.

Kod z opisaną kolejnością:

function loadImageAsync(url) /* [0] stworzenie funkcji */ {
    return /* [9] zwrócenie Promisa */ new Promise((resolve, reject) => { // [2] wykonanie kodu Promisa
        const img=new Image(); // [3]
         
        img.addEventListener("load", (event) =>{
             resolve(img); // [11]*
        }); // [4]
        img.addEventListener("error", reason => {
             reject(new Error(`Failed to load ${url}`)); // [11]*
        }); // [5]
        console.log(img); // [6]
        img.src=url; // [7]
        console.log(img); // [8]
    })
}
 
const image =loadImageAsync("http://thecatapi.com/api/images/get?format=src&type=jpg&size=small") // [1] wywołanie funkcji loadImageAsync i [10] przypisanie zwróconego Promisa do zmiennej
.then(img=>document.querySelector('.image').appendChild(img)) // [12]*
.catch(reason=>console.log(reason)); // [12]*

Gwiazdką oznaczyłem miejsca, gdzie może być wykonany kod z jednej linijki/bloku lub drugiego - w zależności od wystąpienia jednego lub drugiego zdarzenia, a co za tym idzie, spełnienia Promisa lub jego odrzucenia.

Obrazowe wyjaśnienie asynchroniczności na prostych przykładach jest w tej prezentacji: https://www.youtube.com/watch?v=8aGhZQkoFbQ

komentarz 7 czerwca 2020 przez lukas_1994 Nowicjusz (150 p.)
Dzięki wielkie, lepiej się nie dalo chyba wytłumaczyć.
komentarz 8 czerwca 2020 przez lukas_1994 Nowicjusz (150 p.)

"Note that the order of your code does matter. The onload function has to be defined before the src of the image is set:"

Tu miałem problem ze zrozumieniem. smiley 

Podobne pytania

0 głosów
2 odpowiedzi 931 wizyt
pytanie zadane 24 kwietnia 2020 w JavaScript przez maslokeeper01 Użytkownik (620 p.)
+1 głos
2 odpowiedzi 1,121 wizyt
pytanie zadane 9 lipca 2020 w JavaScript przez Greeenone Pasjonat (16,100 p.)
0 głosów
1 odpowiedź 250 wizyt
pytanie zadane 25 czerwca 2020 w JavaScript przez mb-dir Mądrala (6,710 p.)

93,432 zapytań

142,428 odpowiedzi

322,661 komentarzy

62,796 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

...