Javascript JSPromiseAPI:创建一个承诺循环,并将结果合并到另一个对象中
我正在努力理解PromiseAPI 测试用例: 我正在使用三个API,来自 我需要将所有三个API的输出组合成如下结构Javascript JSPromiseAPI:创建一个承诺循环,并将结果合并到另一个对象中,javascript,promise,bluebird,es6-promise,Javascript,Promise,Bluebird,Es6 Promise,我正在努力理解PromiseAPI 测试用例: 我正在使用三个API,来自 我需要将所有三个API的输出组合成如下结构 var user = { 'id' : "1", "name" : "Qwerty", "posts" : [ { "id" : 1, "userid" : 1, "message" : "Hello", "comments" : [
var user = {
'id' : "1",
"name" : "Qwerty",
"posts" : [
{
"id" : 1,
"userid" : 1,
"message" : "Hello",
"comments" : [
{
'id' : 1,
"postId" :1
"userid" : 2,
"message" : "Hi!"
},
{
'id' : 2,
"postId" :1
"userid" : 1,
"message" : "Lets meet at 7!"
}
]
}
]
}
我面临的挑战是将评论合并到每个帖子中。请帮忙。我的意思是我不知道该怎么办
目前的执行情况
var xyz = function (userId) {
return Promise.all(
[
usersApi.getUsersByIdPromise(userId),
postsApi.getPostsForUserPromise(userId)
]
).spread((user, posts) => {
user.posts = posts;
for (let post of user.posts){
commentsApi.getCommentsForPostPromise(post.id)
.then(comments => {
//Merge comments to post
//How do i return a merged user object
});
}
})
}
您的思路是正确的,请参见备注:
var xyz = function (userId) {
// Start parallel requests for user and posts
return Promise.all(
[
usersApi.getUsersByIdPromise(userId),
postsApi.getPostsForUserPromise(userId)
]
).then(([user, posts]) => { // Note the destructuring
// We have both user and posts, let's add the posts to the user
user.posts = posts;
// Send parallel queries for all the post comments, by
// using `map` to get an array of promises for each post's
// comments
return Promise.all(user.posts.map(post =>
commentsApi.getCommentsForPostPromise(post.id)
.then(comments => {
// Have the comments for this post, remember them
post.comments = comments;
})
))
// When all of those comments requests are done, set the
// user as the final resolution value in the chain
.then(_ => user);
});
};
例如:
//模拟
var-id=0;
var usersApi={
GetUsersBydPromise(用户ID){
返回新承诺(解决=>{
setTimeout(=>resolve({id:userId,name:“Some User”}),100);
});
}
};
var postsApi={
getPostsForUserPromise(用户ID){
返回新承诺(解决=>{
setTimeout(=>resolve([
{userId:userId,id:1,标题:“Post 1”},
{userId:userId,id:2,标题:“post2”}
]), 100);
});
}
};
var commentsApi={
getCommentsForPostPromise(postId){
返回新承诺(解决=>{
setTimeout(=>resolve([
{postId:postId,id:++commentId,title:“post id=“+postId}上的第一条评论,
{postId:postId,id:++commentId,title:“post id=“+postId}上的第二条评论,
{postId:postId,id:++commentId,title:“post id=“+postId}上的第三条评论”
]), 100);
});
}
};
//代码
var xyz=函数(用户ID){
//启动用户和帖子的并行请求
回报你的承诺(
[
usersApi.getUsersByIdPromise(userId),
getPostsForUserPromise(用户ID)
]
).then(([user,posts])=>{//注意解构
//我们有用户和帖子,让我们将帖子添加到用户
user.posts=posts;
//通过发送对所有帖子评论的并行查询
//使用“map”获取每个帖子的一系列承诺
//评论
返回Promise.all(user.posts.map)(post=>
commentsApi.getCommentsForPostPromise(post.id)
。然后(注释=>{
//请记住这篇文章的评论
post.comments=评论;
})
))
//完成所有这些注释请求后,设置
//用户作为链中的最终分辨率值
。然后(=>user);
});
};
//使用它
xyz()。然后(用户=>{
log(JSON.stringify(user,null,2));
});代码>
。作为控制台包装器{
最大高度:100%!重要;
}
您尝试对承诺的结果使用的传播
方法是什么。所有
?在标准Promise API中没有spread
,请在标准Promise API中给出解决方案。您应该将post.comments=post
更改为post.comments=comments
@nicowernli:LOL,是的,是的,我应该,谢谢。:-)(编辑:已修复)@T.J.Crowder抱歉,两者都不适用于我,我正在作为节点应用程序运行。也没有错误.then(=>{console.log(posts);resolve(posts)})
此处不打印任何内容。可能是环境出了问题。另外,我不得不将[user,posts]
更改为(user,posts)
@titogeo:在第二个示例中,我有一个小的语法错误(您需要()
)和一个小的嵌套错误。这里不应该有任何特定于环境的内容。我已经修复了上面的这些小错误,并添加了实时示例。@titogeo:v2允许更多的重叠,因此可以更快地完成:如果对帖子的查询在对用户的查询之前完成,它不会等到用户查询完成后再请求注释。v1等待post和user都进入,然后才请求评论。
var xyz = function (userId) {
// Start parallel requests for user and posts
return Promise.all(
[
usersApi.getUsersByIdPromise(userId),
postsApi.getPostsForUserPromise(userId)
]
).then(([user, posts]) => { // Note the destructuring
// We have both user and posts, let's add the posts to the user
user.posts = posts;
// Send parallel queries for all the post comments, by
// using `map` to get an array of promises for each post's
// comments
return Promise.all(user.posts.map(post =>
commentsApi.getCommentsForPostPromise(post.id)
.then(comments => {
// Have the comments for this post, remember them
post.comments = comments;
})
))
// When all of those comments requests are done, set the
// user as the final resolution value in the chain
.then(_ => user);
});
};