如何通过维护异步/并发流和结果格式,以更易读的方式编写下面的代码。
var getUsers = () => axios.get("URL").then(res => res.data);
var getPosts = id => axios.get("URL").then(res => res.data);
var getComments = id => axios.get("URL").then(res => res.data);
Promise.map(getUsers(), user => {
return getPosts(user.id).then(posts => {
return Promise.map(posts, post => {
return getComments(post.id).then(comments => {
post["comments"] = comments;
user["posts"] = posts;
return user;
});
});
});
})
.then(res => console.log(JSON.stringify(res)))
.catch(err => console.log(err));
样本格式:
[
{
id:''
name:'..',
email:'',
phone:''
posts:[
{
postId:'...',
title:'....'
body:'....'
comments: [{body:'....'},{body:'...'}]},
{
postId:'...',
title:'....'
body:'....'
comments: [{body:'....'},{body:'...'}]
}
]
}
]
除了下面的getUsers()之外的每个api都取决于某些args的先前api。 我正在使用蓝鸟承诺库。 Node Js版本:v9.3.0
编辑:我也尝试过使用3 Promise.map:
var getPosts = id => axios.get("URL").then(res => res.data).then(posts => {
user["posts"] = posts;
return user;
});
var getComments = user => {
return Promise.map(user.posts, post => {
return axios.get(URL).then(res => res.data).then(comments => {
post["comments"] = comments;
return user;
}).then(users => users[0]);
getUsers()
.then(users => Promise.map(users, getPosts))
.then(users => Promise.map(users, getComments))
.then(res => console.log(JSON.stringify(res)))
.catch(err => console.log(err));
答案 0 :(得分:0)
为了使您的代码更具可读性,并防止丑陋Promise hell
您应该使用async/await
语法。
async function foo() {
async function getUsers() {
var res = await axios.get("URL")
return res.data
}
async function getPosts(id) {
var res = await axios.get("URL")
return res.data
}
async function getComments(id) {
var res = await axios.get("URL")
return res.data
}
var users = await getUsers()
for (var user of users) {
var posts = await getPosts(user.id)
for (var p of posts) {
var comments = await getComments(p.id)
p['comments'] = comments
}
user['posts'] = posts
}
return users
}
然后你就像这样使用
foo()
.then(users => console.log(users))
.catch(e => console.log('Whatever throw or reject inside foo', e))
如果是我,我会做这样的事情
async function foo() {
var users = await axios.get("users URL")
for (var user of users.data) {
var posts = await axios.get("post URL" + user.id)
for (var p of posts.data) {
var comments = await axios.get("comments URL" + p.id)
p['comments'] = comments.data
}
user['posts'] = posts.data
}
return users.data
}
答案 1 :(得分:0)
我不会说它特别难以辨认。循环需要嵌套。一个小的改进可能是使用prototype .map
method而不是Promise.map
:
getUsers().map(user =>
getPosts(user.id).map(post => {
getComments(post.id).then(…)
)
).then(res =>
console.log(JSON.stringify(res))
).catch(err =>
console.error(err)
);
但是,您的代码中似乎存在严重错误。您正在将帖子映射到用户,这会导致用户为他发布的每个帖子重复,并省略完全没有帖子的用户。这可能不是你想要的。相反,在获取帖子和评论后返回用户。
getUsers().map(user =>
getPosts(user.id).map(post => {
getComments(post.id).then(comments => {
post["comments"] = comments;
return post;
})
).then(posts => {
user["posts"] = posts;
return user;
})
).then(users => {
console.log(JSON.stringify(users));
}).catch(console.error);
或者我们可以保留我们正在改变其内容的数组,但是如果我们想要访问数组,我们需要使用then
而不是map
。
getUsers().then(users =>
Promise.map(users, user =>
getPosts(user.id).then(posts => {
user.posts = posts;
return Promise.map(posts, post =>
getComments(post.id).then(comments => {
post["comments"] = comments;
})
);
})
).then(() =>
console.log(JSON.stringify(users))
)
).catch(console.error);