Problem z .then()

adams0
  • Rejestracja:prawie 8 lat
  • Ostatnio:dzień
  • Postów:317
0

Cześć !

Nie rozumiem do końca działania .then() .
Wiem że wykonuje on callback jeśli promise dostanie status "resolved" a potem zwraca kolejny promise.

Chciałem pobrać dane postaci ze Star Wars.
Ten kod loguje mi bohatera:

Kopiuj
function getHero(url) {
  fetch(url)
    .then(data => data.json())
    .then(hero => console.log(hero));
}
getHero("https:/swapi.co/api/people/13/")

a ten nie:

Kopiuj
function getAnotherHero(url) {
  fetch(url).then(data => console.log(data.json()));
}
getAnotherHero("https:/swapi.co/api/people/14/");

Dla czego getAnotherHero nie wykonuje console.log() ?

.__.
  • Rejestracja:ponad 5 lat
  • Ostatnio:prawie 5 lat
0

W pierwszym then ustalasz w jaki sposób mają zostać zwrócone dane (np json), a w drugim je odbierasz

qqq.png

  • qqq.png (38 KB) - ściągnięć: 88
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
1

Zwróć uwagę na to, co zwraca metoda json.


złoty
  • Rejestracja:ponad 17 lat
  • Ostatnio:28 dni
  • Lokalizacja:Warszawa
  • Postów:108
1
.__. napisał(a):

W pierwszym then ustalasz w jaki sposób mają zostać zwrócone dane (np json), a w drugim je odbierasz

Nie zgadzam się.
Ustalanie typu danych, jaki ma być zwrócony z serwera odbywa się poprzez nagłówek Accept.
W pierwszym then lambda przyjmuje jako argument obiekt odpowiedzi, i zwraca Promise, którego wynikiem jest sparsowanie otrzymanej już odpowiedzi jako JSON.

adams0
  • Rejestracja:prawie 8 lat
  • Ostatnio:dzień
  • Postów:317
0

Wiem że metoda .json() wyciąga z całej odpowiedzi z serwera "mięso" (body) i zwraca obiekt.

Ale dalej nie mam wyjaśnienia dla czego drugi zapis nie działa. Wydawało mi się że one są sobie równoważne ?

MA
  • Rejestracja:prawie 17 lat
  • Ostatnio:9 dni
  • Postów:644
1
Kopiuj
function getAnotherHero(url) {
  fetch(url).then(async data => console.log(await data.json()));
}
getAnotherHero("https://swapi.co/api/people/14/");

data.json() to też funkcja która zwraca Promise, console.log się wykonuje (chociaż miałeś literówkę w URL) z Promise, ale jak dodasz await to będziesz miał już dane wynikowe.

edytowany 1x, ostatnio: Markuz
SushiTrash
  • Rejestracja:prawie 7 lat
  • Ostatnio:około 5 lat
  • Postów:41
1

Bo w pierwszym .then() w body nie ma jeszcze "obiektu" jest natomiast ReadableStream który trzeba sobie obsłużyć. Metoda .json() robi to za ciebie i zwraca kolejnego promisa który po wykonaniu się zwraca sparsowany response:

Kopiuj
fetch(url)                                           
  .then(data => data.json())  // metoda json jest jedna z metod konwersji z strumienia danych na promisa z wynikiem, w tym miejscu body jeszcze nie zostalo pobrane
  .then(console.log);         // po tym jak promise zwrocony przez data.json() zostanie rozwiazany, zwroci on wynik z ReadableStream

Tak wiec twoj drugi kawalek kodu bedzie dzialac jezeli zmienisz go troche:

Kopiuj
function getAnotherHero(url) {
  fetch(url).then(data => data.json().then(console.log)); // ten kod dziala tak samo jak ten powyzej
}
getAnotherHero("https://swapi.co/api/people/14/");

Szczegolowiej:
https://developer.mozilla.org/en-US/docs/Web/API/Body/json
https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream

edytowany 9x, ostatnio: SushiTrash

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.