使用fetch和promises的Rithim异步Java脚本练习

问题描述 投票:-2回答:1

我被困在老少皆宜的练习中,我终于把毛巾扔了,并寻求帮助。

对《星球大战》 API [https://swapi.co/]进行AJAX调用,并获得该系列中每部电影的开幕片。完成此操作后,循环遍历每部电影的行星排列,并进行更多的AJAX调用以收集按电影组织的每个行星的名称。然后,控制台记录一个对象数组,其中每个对象都包含特定电影的开头抓取,以及该电影中每个行星的名称。

我已经阅读了几篇文章,并观看了一些有关异步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"
    //  }]

几乎可以正常工作,我可以返回一个对象。提取数组根本不起作用。而且我第二次尝试检索行星名称的更改无效。

javascript ajax promise fetch
1个回答
0
投票

首先,将函数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));
© www.soinside.com 2019 - 2024. All rights reserved.