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});
});