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

Posted

技术标签:

【中文标题】.then() 在嵌套的 promise.all 和 fetch 完成之前执行【英文标题】:.then() is executed before nested promise.all and fetch are done 【发布时间】:2019-09-28 20:43:46 【问题描述】:

我正在尝试创建一个应用程序,该应用程序使用 javascript 中的 fetch 从 API 检索数据。这是几个 url 的 JSON 结构

myapi.com/list 返回: [id:111, 用户:nam1,id:222, 用户: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】:

你的问题在这里:

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 永远不会返回,因此您的主要承诺在fetchs 之前解决。另请注意,map 不是 mutator,如果您希望将其包含在新数组中,则必须返回一个值。

试试这个:

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)

【讨论】:

非常感谢您帮助我。你无法想象我有多感激。我一直在尝试您建议的每个编辑。您的最终编辑工作完美。我只需要“posts”作为完整数组,而不仅仅是第一个对象,所以我删除了 [0]。非常感谢你,再次感谢!

以上是关于.then() 在嵌套的 promise.all 和 fetch 完成之前执行的主要内容,如果未能解决你的问题,请参考以下文章

Promise.all 的 then() 函数在 Promise 完成之前执行 - Ionic/Angular

React Native 为啥我的代码在完成任务之前执行? Promise.all().then() 异步问题

.then 的 Promise.all 没有执行

在嵌套 forEach 中的 Promise.all 之前评估 Promise,导致 Promise.all 为空

Promise.all:解析值的顺序

带有嵌套地图的 Promise.all .. 第一张地图仅适用于其他人在猫鼬中返回空对象