axios和promises,数组值不可用但出现在console.log中

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

我已经嵌套了axios调用,所以使用promises来构建我将用于我的应用程序的数据数组。

第一次调用获取标题或剧集列表。

第二次调用获取第一次收到的剧集网址以获取其他数据。然后我将属性添加到我想在我的应用程序中使用的数据数组。这些是标题和图片网址[0]。

第三个调用然后获取image_urls [0]并进行调用以检索该实际图像。现在它在这个调用中,当我使用console.log或对第二次调用中添加的值做任何事情时,我得到了未定义,但是如果我在console.log我的完整数组中显示值!

 console.log("sections", sections); // show all the data including 2nd call
 console.log("image url", item.url); // This shows
 console.log("image title", item.title); // This doesn't and don't know why
 console.log("image imageurls", item.imageurls); // This doesn't and don't know why

这是我的代码

import axios from 'axios';

let sections = new Array(),
    section = null,
    episodes = null;

const dataService =
axios
    .get('http://feature-code-test.skylark-cms.qa.aws.ostmodern.co.uk:8000/api/sets/coll_e8400ca3aebb4f70baf74a81aefd5a78/items/')
    .then((response) => {

    var data = response.data.objects;

    Promise.all(data.map(function (item) {
        let type = item.content_type.toLowerCase();

        if (type !== "episode") {
            if (section !== null) {
                section.episodes = episodes;
                sections.push(section);
            }
            section = new Object();
            episodes = new Array();
            section.header = item.heading;
        }

        if (type === "episode") {
            var episode = new Object();
            episode.url = item.content_url;
            episodes.push(episode)
        }
    })).then(function () {
        section.episodes = episodes;
        sections.push(section);

        Promise.all(sections.map(function (item) {
            Promise.all(item.episodes.map(function (item) {
                var url = `http://feature-code-test.skylark-cms.qa.aws.ostmodern.co.uk:8000${item.url}`
                axios
                    .get(url)
                    .then((response) => {
                    var data = response.data;

                item.title = data.title;
                item.imageurls = data.image_urls[0] !== undefined ? data.image_urls[0] : "";
            });

            }))
        })).then(function () {
            Promise.all(sections.map(function (item) {
                Promise.all(item.episodes.map(function (item) {
                    console.log("sections", sections);
                    console.log("image urr", item.url);
                    console.log("image title", item.title);
                    console.log("image imageurls", item.imageurls);
                }));
            }));
        });;
    })
})

export default dataService
javascript arrays reactjs es6-promise axios
1个回答
1
投票

以下应该适合你,我认为你必须花一点时间研究承诺,映射和减少。

我摆脱了axios并使用fetch所以有可能在浏览器中测试它时,在网站上打开一个api page并在控制台中运行代码(没有导出行,用const替换const)。

如果您需要任何帮助,请告诉我。

const base = "http://feature-code-test.skylark-cms.qa.aws.ostmodern.co.uk:8000";
const setEpisodeDetails = episode =>
  fetch(`${base}${episode.url}`)
    .then(response=>response.json())
    .then(
      data =>
        Object.assign(
          {}
          ,episode
          ,{
            title : data.title,
            imageurls : data.image_urls[0] || ""
          }
        )
    )
    .then(//fetch image url
      episode =>
        (episode.imageurls!=="")
          ? fetch(`${base}${episode.imageurls}`)
            .then(response=>response.json())
            .then(
              imageData=>
                Object.assign(
                  {},
                  episode,
                  {
                    image_content_url:imageData.url
                  }
                )
            )
          : episode
    );
const setAllEpisodeDetails = sections =>
  Promise.all(
    sections.map(
        section =>
          Promise.all(
            section.episodes.map(
              setEpisodeDetails
            )
          )
          .then(
            episodes =>
              Object.assign(
                {},
                section,
                {episodes}
              )
          )

    )
  );
const createSections = data =>
  data.reduce(
    (acc,item)=>{
      (item.content_type.toLowerCase()!=="episode")
        ? acc.push({header:item.heading,episodes:[]})
        : acc.slice(-1)[0].episodes.push({url:item.content_url})
      return acc
    },
    []
  );
const dataService =
  fetch(`${base}/api/sets/coll_e8400ca3aebb4f70baf74a81aefd5a78/items/`)
    .then(response=>response.json())
    .then(
      response =>
        setAllEpisodeDetails(createSections(response.objects))
    )
    .then(
      sections =>
          console.log(
            "sections", 
            JSON.stringify(sections,undefined,2)
          ) || //remove this console log if it works
          // (can remove the whole last then)
          //do not remove this it returns sections (unless you get rid of the whole then)
          sections
    );

//removed export, should log the result when done (or error)
© www.soinside.com 2019 - 2024. All rights reserved.