简体   繁体   English

Rithim 异步 Javascript 练习使用 fetch 和 promises

[英]Rithim Asynchronous Javascript exercises using fetch and promises

I've been stuck working on this exercise FOR AGES, I'm finally throwing in the towel and asking for some help.我一直坚持这项练习很多年了,我终于认输并寻求帮助。

Make an AJAX call to the Star Wars API [ https://swapi.co/] and get the opening crawl for each film in the series.对 Star Wars API [ https://swapi.co/]进行 AJAX 调用,并获取该系列中每部电影的开头抓取。 Once you have finished that, loop through the array of planets for each movie and make more AJAX calls to collect the name of each planet, organized by film.完成后,循环遍历每部电影的行星数组,并进行更多 AJAX 调用以收集按电影组织的每个行星的名称。 Then, console log an array of objects in which each object contains the opening crawl for a specific movie, along with the names of every planet featured in that movie.然后,控制台记录一个对象数组,其中每个对象都包含特定电影的开头爬行,以及该电影中出现的每个行星的名称。

I've read a few articles and watched a few videos on Asynchronous js, and I 'think?', I sorta get it.我已经阅读了一些关于异步 js 的文章并观看了一些视频,我“认为?”,我有点明白了。 This really doesn't want to work though.这真的不想工作。

    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"
    //  }]

It almost works I can return an object.它几乎可以工作,我可以返回一个对象。 The fetch arrays doesn't work at all.获取数组根本不起作用。 and my second alteration attempting to retrieve the planet name doesn't work.我试图检索行星名称的第二次更改不起作用。

First, rename function fetchArray as fetchPlanetNames , as that's what it does, and add a couple of missing returns.首先,将函数fetchArray重命名为fetchPlanetNames ,正如它所做的那样,并添加一些缺失的返回值。 Then you have a worker function that makes the main code block much simpler ( as was your intention :-) ).然后你有一个工作函数,它使主代码块更简单(正如你的意图:-))。

In the main code block, fetchPlanetNames(...) returns Promise, not Array, therefore, inside the films.map() functor, you need fetchPlanetNames(film.planets).then(planets => {/* compose the required film object here */}) .在主代码块中, fetchPlanetNames(...)返回的是 Promise,而不是 Array,因此,在films.map()函子中,您需要fetchPlanetNames(film.planets).then(planets => {/* compose the required film object here */}) It's a kind of "inside-out" version of what you tried.这是您尝试的一种“由内而外”的版本。

 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));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM