.then()在嵌套promise.all和fetch完成之前执行

时间:2019-05-10 23:50:11

标签: javascript json api es6-promise fetch-api

我正在尝试创建一个应用,该应用使用Javascript中的抓取功能从API检索数据。这是几个网址的JSON结构

myapi.com/list返回: [{id:111,user:nam1},{id:222,user:nam2}] 然后,我必须使用其中一个ID进行另一个请求 示例:myapi.com/list/111返回:

[{id:111,user:name1,description: "some text",public:true}]

示例:myapi.com/list/111/posts返回:

[{a1:"some data",a2:"some data2"},{b1:"some data",b2:"some data2"},{c1:"some data",c2:"some data2"}]

出于几个原因,我需要创建一个函数,该函数以以下格式返回将所有这些分组的1个数组:

   [
    {id:111,user:name1,description: "some text",public:true, 
    posts:[{a1:"some data",a2:"some data2"},{b1:"some data",b2:"some data2"},{c1:"some data",c2:"some data2"}]
    },
    {id:222,user:name2,description: "some text2",public:true
    posts:[{a1:"some data",a2:"some data2"},{b1:"some data",b2:"some data2"},{c1:"some data",c2:"some data2"}
    }
    ]

这是我的主程序 由于setTimeOut,该方法工作正常:

    Promise.all([FetchFunctionThatworks(),FetchfunctionWithPrblm() ])
    .then(values => new State(values[0], values[1]))
    .then(state => {console.log(state) ; 

      setTimeout(function(){
      functionA(state); // a function that prints some html with the result of the FetchfunctionWithPrblm

  },200)
   ;} )
    .catch(reason => console.error(reason));

我希望删除setTimeout,但是问题是我的.then()内部的代码在承诺被解决之前调用functionA,因此我得到的结构缺少“帖子”,而setTimeOut则得到了所需的输出。

这是我的FetchfunctionWithPrblm()

function FetchfunctionWithPrblm() {
  const url = serverUrl+ "list/";
   return fetch(url).then(
    id_list => id_list.json()
  ).then(
    list_data => Promise.all(
      list_data.map(topic => fetch(url +topic.id)
      .then(response =>  response.json()  )
      )
    ) /**end 1st promise.all */

  ) .then(ListNopost =>{
    ListNopost.map( single_entry =>{
      Promise.all( [fetch( url + single_entry.id+ '/posts').then(resp=>resp.json() ) ] )
      .then (posts_data =>{
        single_entry.posts=posts_data[0];
      })
    })
    return ListNopost;
  })
}

不是promise.all应该只在promise解决后才返回吗? 有人可以告诉我我在做什么错吗?并帮助我修复它吗?

预先感谢

1 个答案:

答案 0 :(得分:3)

您的问题在这里:

ListNopost.map( single_entry =>{
   Promise.all( [fetch( url + single_entry.id+ '/posts').then(resp=>resp.json() ) ] )
   .then (posts_data =>{
     single_entry.posts=posts_data[0];
   })
})
return ListNopost;

Promise.all从未返回,因此您的主要承诺在fetch之前就解决了。还要注意,map不是一个变量,如果您希望将其包含在新数组中,则必须返回一个值。

尝试一下:

var promises = ListNopost.map(single_entry => {
    return fetch(url + single_entry.id + '/posts')
        .then(resp => resp.json())
        .then(posts_data => {
            single_entry.posts = posts_data[0]
            return single_entry
        })
})
return Promise.all(promises)