Javascript axios和promises,数组值不可用,但显示在console.log中

Javascript axios和promises,数组值不可用,但显示在console.log中,javascript,arrays,reactjs,es6-promise,axios,Javascript,Arrays,Reactjs,Es6 Promise,Axios,我有嵌套的axios调用,因此使用承诺来构建我将用于我的应用程序的数据数组 第一个调用获取标题或剧集的列表 第二个调用获取第一个调用中接收到的插曲url以获取附加数据。然后将属性添加到要在应用程序中使用的数据数组中。 这些是标题和图像URL[0] 然后,第三个调用获取图像URL[0],并调用以检索该实际图像。现在,在这个调用中,当我使用console.log或对第二个调用中添加的值执行任何操作时,我都会得到未定义的值,但是如果我使用console.log,则会显示完整的数组中的值 consol

我有嵌套的axios调用,因此使用承诺来构建我将用于我的应用程序的数据数组

第一个调用获取标题或剧集的列表

第二个调用获取第一个调用中接收到的插曲url以获取附加数据。然后将属性添加到要在应用程序中使用的数据数组中。 这些是标题和图像URL[0]

然后,第三个调用获取图像URL[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

下面的内容应该对你有用,我认为你必须花一点时间来研究承诺、映射和减少

我去掉了axios并使用了fetch,这样当在站点上打开一个并在控制台中运行代码时,就可以在浏览器中测试它(不使用导出行并用var替换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)

您一直在使用
map()
,但从未向这些映射的数组返回任何内容<代码>承诺。所有([undefined,undefined])都是无用的,不会等待任何东西。在链接的
then()中也不返回任何内容s@charlietfl你能给我看一个修改上述代码的例子吗?@charlietfl我正在映射的数组我正在更新。你能解释一下为什么在我控制台记录分区数组时会出现这些值,而在我第三次调用中记录项目属性时不会出现这些值。首先,只在需要的地方使用承诺-代码的快速而肮脏的重写(我想)是-只注意一个承诺。所有。。。与代码中5个不必要的承诺相比。。。使用forEach,因为在你的代码中根本不需要.map——然而,这是一个快速而肮脏的重写,你的代码可以被编写——老实说,我仍然不理解或者不喜欢第一个“循环”。最后,
dataService
将是一个承诺,它将解析为
未定义的
,与您的原始代码相同-因为我无法告诉您希望
dataService
真正正常。不了解其中的大部分,因此将进行一些研究。将尝试在加载实际images@Adam如果在现代浏览器中打开,您可以检查输出是否正确(最新的Chrome浏览器也可以)。按F12并在控制台中粘贴代码。用
dataService替换
export default dataService
。然后(result=>console.log(JSON.stringify(result,undefined,2))
Yes我可以看到它正在工作。我不知道如何扩展它,在seteposodedetails之后向api发出另一个请求,以使用event.imageURL检索实际图像。你能给我看看吗?@Adam你的意思是获取并存储为base64的图像?我不知道怎么做,但明天可以查一下。您可以尝试编写一个函数,获取url并获取图像,将其存储为base64并将其设置为img html元素。您无法下载图像,因为您有url,因此可以添加第一部分()并将其用于img src属性。我不确定您的代码是否在
http://feature-code-test.skylark-cms.qa.aws.ostmodern.co.uk:8000
如果没有,代码可能根本不起作用,因为我看不到allow origin标头。no not base64。它从中获取的eposion.imageURL值是一个api端点。从该端点开始,其中一个属性是实际的绝对图像路径。因此,我只需要在调用后获取实际图像。