How to use promise to avoid callback hell?
This question already has an answer here:
Try whit this:
function getPost(id) {
return Post
.findOne({id: id})
.then( post => {
return post;
});
}
using Q module
function getCommentsAndLinks(post) {
return Q.all([
Comment.find({id: post.id}),
Links.find({id: post.id})
])
.done( results => {
let comments = results[0];
let links = results[1];
return [post, comments, links];
})
.catch( err => {
// handle err
})
on controller
getPost(postId)
.then(getCommentsAndLinks)
.then( results => {
let post = results[0];
let comments = results[1];
let links = results[2];
// more code here
})
.catch( err => {
// handle err
})
but i suggest you not save string of IDS, save the instance of object, so you can use populate to get all data of comments and links, something like this:
Post
.findOne({id: id})
.populate('comments')
.populate('links')
.then( post => {
// here have the post with data of comments and links
});
You are nesting the callbacks. You don't need to do this. If you return a promise from .then
then any .then
you chain to it will be resolved when that promise gets resolved:
promise.then(post => Comments.find({id: post.id})
.then(comments => Links.find({id: post.id})
.then(links => {});
The comments query does not depend on links so you can actually do both queries at once:
promise.then(post => {
return Promise.all([
post,
Comments.find({id: post.id}),
Links.find({id: post.id}),
]);
}).then(data => res.json({
post: data[0],
comments: data[1],
links: data[2],
});
If you use a library like bluebird you can also use something like the spread
operator to make the names more transparent.
I would also look into using co for generator-based control flow as I think this is even clearer:
co(function* () {
const post = yield Posts.findOne({id});
const [comments, links] = yield [
Comments.find({id: post.id}),
Links.find({id: post.id}),
];
res.json({post, comments, links});
});
The advantage of using promises is you can chain them, so your code can be reduced to:
let post, comments;
Posts.findOne({id: id}).exec().then(_post => {
post = _post;
return Comments.find({id: post.id}).exec();
}).then(_comments => {
comments = _comments;
return Links.find({id: post.id}).exec();
}).then(links => res.json({post, comment, links}))
.catch(error => res.error(error.message));
you would notice that I needed only a single catch block.
链接地址: http://www.djcxy.com/p/55440.html上一篇: 回调还是承诺?
下一篇: 如何使用promise来避免回调地狱?