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

JS - promise

Object Storage Arubacloud
0 głosów
233 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 469 wizyt
pytanie zadane 24 kwietnia 2020 w JavaScript przez maslokeeper01 Użytkownik (620 p.)
+1 głos
2 odpowiedzi 652 wizyt
pytanie zadane 9 lipca 2020 w JavaScript przez Greeenone Pasjonat (16,100 p.)
0 głosów
1 odpowiedź 205 wizyt
pytanie zadane 25 czerwca 2020 w JavaScript przez mb-dir Mądrala (6,710 p.)

92,579 zapytań

141,432 odpowiedzi

319,664 komentarzy

61,964 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...