Ритим Асинхронные Javascript упражнения, используя выборки и обещания - PullRequest
0 голосов
/ 17 января 2020

Я застрял, работая над этим упражнением ДЛЯ ВОЗРАСТОВ, наконец-то бросаю полотенце и прошу помощи.

Сделайте AJAX вызов API Star Wars [ https://swapi.co/] и получите начальный обход для каждого фильма в серии. Как только вы закончите это, l oop через массив планет для каждого mov ie и сделайте больше AJAX звонков, чтобы собрать имя каждого pl anet, организованного фильмом. Затем консоль регистрирует массив объектов, в котором каждый объект содержит начальный обход для указанного c mov ie вместе с именами каждого pl anet, представленного в этом mov ie.

* 1007. * Я прочитал несколько статей и посмотрел несколько видео об Асинхронном js, и я «думаю?», Я как-то понял. Это действительно не хочет работать, хотя.
    var promiseList = [];

    var fetchArray = function(arr) {
      promiseArr = arr
        .map(url => fetch(url)
            .then(res => res.json())
            .then(planet => planet.name)
            );     
      Promise.all(promiseArr)
        .then(data => console.log(data));
    }
    // fetchArray doesn't work at all. Curious if it's possible to run this code as it's technicall synchronous (idk).

    for (let number = 1; number < 8; number ++) {
      var t = fetch(`https://swapi.co/api/films/${number}/`)
       .then(res => res.json())
        promiseList.push(t)
    }

    console.log("NAHANH", promiseList)
    // Prints out [[object Promise] { ... }, [object Promise] { ... }, [object Promise] { ... }, [object Promise] { ... }, 
    [object Promise] { ... }, [object Promise] { ... }, [object Promise] { ... }]

    Promise.all(promiseList)
      .then(films => films.map(film => ({
        "title": film.title,
        "planets": film.planets,
        "opening_crawl": film.opening_crawl,
      })))
    // Works up untill this point, this next then doesn't work, my aim is to alter the film.plants property in every 
    array object and actually fetch the planet rather than just the url!
    // An example print out would be...
    // {
    //  opening_crawl: "Luke Skywalker has vanis...",
    //  planets: ["https://swapi.co/api/planets/61/"],
    //   title: "The Force Awakens"
    //  }]
      .then(films => films.map(film => {
          film.planets = film.planets
            .map(url => fetch(url)
              .then(res => res.json())
              .then(planet => planet.name)
              .catch(error => console.log(error.message))
            );     
      }
      .then(data => console.log(data))
    // Which would then finally resolve to (this is what I want but cannot get at the moment!) 
    //  {
    //    opening_crawl: "Luke Skywalker has vanis...",
    //    planets: ["Yavin IV"],
    //    title: "The Force Awakens"
    //  }]

Это почти работает, я могу вернуть объект. Массивы выборки не работают вообще. и моя вторая попытка получить имя pl anet не работает.

1 Ответ

0 голосов
/ 17 января 2020

Во-первых, переименуйте функцию fetchArray в fetchPlanetNames, поскольку это то, что она делает, и добавьте пару пропущенных возвратов. Тогда у вас есть рабочая функция, которая делает блок основного кода намного проще (как и было задумано :-)).

В блоке основного кода fetchPlanetNames(...) возвращает Promise, а не Array, поэтому внутри films.map() функтор, вам нужно fetchPlanetNames(film.planets).then(planets => {/* compose the required film object here */}). Это своего рода "изнутри" версия того, что вы пробовали.

var fetchPlanetNames = function(arr) {
	return Promise.all(arr.map(url => { // return the Promise returned by Promise.all(...).then(...)
     // ^^^^^^
		return fetch(url)
		.then(res => res.json())
		.then(planet => planet.name);
	}))
	.then(data => {
		console.log(data);
		return data; // Remember to return `data`, otherwise undefined will be dlivered.
	     // ^^^^^^^^^^^^
	});
};

var promiseList = [];
for (let number = 1; number < 8; number ++) {
	promiseList.push(fetch(`https://swapi.co/api/films/${number}/`).then(res => res.json()));
}
Promise.all(promiseList)
.then(films => {
	return Promise.all(films.map(film => {
		// Here, a nested Promise chain allows `film` to remain in scope at the point where 'planets' become available.
		return fetchPlanetNames(film.planets)
		.then(planets => {
			return {
				'title': film.title,
				'planets': planets,
				'opening_crawl': film.opening_crawl
			};
		});
	}));
})
.then(data => console.log(data));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...