W poniższym kodzie jest błąd, ale nie mogę tego rozgryźć. Wierzyłem, że kiedy zrobię Obietnicę. Wszystko (...). Wtedy wszystkie obietnice powinny się skończyć w tym momencie, ale na to nie wygląda. . Kod po prostu pobiera kilka plików jsonów z interfejsu API, a następnie dodaje kilka elementów HTML do DOM. Ale w jakiś sposób te nowe elementy nie są rejestrowane w późniejszej części Promise.all.

let urls = [];

urls.push(someurl);
urls.push(someurl2);

Promise.all(urls.map(url => {
    fetch(url)
        .then(response => {
            return response.json();
        })
        .then(data => {

            ... // do something with the current json and add some <option> elements to the DOM

            let options = document.querySelectorAll('option');
            console.log(options); //is filled with the correct options!


        })
})).then(data => {

    let options = document.querySelectorAll('option');
    console.log(options); // IS EMPTY!!! I expected to see the two sets of the <option> elements

});

Wynikowy kod HTML wygląda tak, jak powinien na frontendzie, ale DOM w. To nie jest w takim stanie, w jakim się tego spodziewałem. Z tego powodu mam problemy z biblioteką materializecss, ponieważ nie mogę wypełnić listy rozwijanej wyboru elementami. To tak, jakby nie zostały jeszcze utworzone w momencie, w którym inicjalizuję listę rozwijaną wyboru w., A następnie. Dzięki za pomoc!

ROZWIĄZANIE: właśnie umieściłem zwrot przed pobraniem !! Dziękuję wszystkim, którzy wskazali mi właściwy kierunek. Nie wiem dokładnie, dlaczego Promise.all (...). Wykonywany nawet bez prawidłowego zwrotu, ale to naprawiło.

1
Morgus Lethe 2 kwiecień 2020, 17:30

3 odpowiedzi

Najlepsza odpowiedź

Nie wiem dokładnie, dlaczego Promise.all (...). Wykonywany nawet bez prawidłowego zwrotu, ale to naprawiło.

Bez return, którego brakowało, przekazałeś Promise.all() tablicę wartości undefined. Ponieważ w tej tablicy nie było żadnych obietnic, Promise.all() nie miał na co czekać, więc natychmiast wywołał swoją procedurę obsługi .then(). Dlatego został wykonany bez czekania na zakończenie. Musisz przekazać Promise.all() tablicę obietnic, jeśli chcesz, żeby czekała.

1
jfriend00 2 kwiecień 2020, 15:39

Możesz spróbować zaktualizować metodę map(), aby zwracała odpowiedź pobierania, na przykład:

Promise.all(urls.map(url => fetch(url).then(resp => resp.json())))
   .then(data => {
      console.log(data);

      let options = document.querySelectorAll('option');
      console.log(options);
   })

Pamiętaj, że w ES5 zrobilibyśmy coś takiego:

var multiply = function(x, y) {
  return x * y;
};

Aw ES6 możemy użyć funkcji strzałki takiej jak:

const multiply = (x, y) => { return x * y };

Tutaj wymagana jest instrukcja return, w przeciwnym razie zwróci wartość undefined, ale instrukcja wewnątrz { ... } będzie nadal wykonywana, tylko obliczona wartość nie zostanie zwrócona. Zatem w twoim kodzie fetch działało, ale ostatnie .then nie.

Ponadto nawiasy klamrowe nie są wymagane, jeśli występuje tylko jedno wyrażenie. Tak więc poprzedni przykład można również zapisać jako:

const multiply = (x, y) => x * y;
2
palaѕн 2 kwiecień 2020, 14:58

Rozwiązanie: brak powrotu przed pobraniem. Nie wiem, dlaczego .then działał nawet bez tego powrotu, ale to rozwiązało problem. Innym rozwiązaniem byłoby usunięcie nawiasów klamrowych w tym przykładzie. Teraz wszystko działa dokładnie tak, jak się tego spodziewam.

0
Morgus Lethe 2 kwiecień 2020, 15:32