问题
const returnPostData = async (req, res, initialPostsQueryArray) => {
try{
const promises = initialPostsQueryArray.map( async (post) => {
let voteCount = 0;
let voted = false;
let liked = false;
let userHandle;
let userImageUrl;
let votingOptionsDictionary;
let userVoteOption;
voteCount = sumValues(post.voting_options);
pool.query('SELECT userhandle, image_url FROM users WHERE id = $1 ',
[post.user_id],
(error, results) => {
if (error) {
console.log(error);
return res.json({'Error': error.detail});
}
const userPostquery = results.rows[0];
userHandle = userPostQuery.userhandle;
userImageUrl = userPostQuery.image_url;
pool.query('SELECT EXISTS( SELECT 1 FROM likes WHERE user_id = $1 AND post_id = $2)',
[req.user.userId, post.post_id],
(error, results) => {
if (error) {
console.log(error);
return res.json({'Error': error.detail});
}
// if the user like exists, set liked = true
if(results.rows[0].exists == true){
liked = true;
}
pool.query('SELECT EXISTS( SELECT 1 FROM votes WHERE user_id = $1 AND post_id = $2)',
[req.user.userId, post.post_id],
(error, results) => {
if (error) {
console.log(error);
return res.json({'Error': error.detail});
}
// if the user vote exists, set voted = true and query for what they voted for
if(results.rows[0].exists == true){
voted = true;
votingOptionsDictionary = post.voting_options;
pool.query('SELECT voting_option FROM votes WHERE user_id = $1 AND post_id = $2',
[req.user.userId, post.post_id],
(error, results) => {
if (error) {
console.log(error);
return res.json({'Error': error.detail});
}
userVoteOption = results.rows[0].voting_option;
});
}
// i dont need voteCount here because that is calculated after the first query, this gets all the counts of the posts
pool.query('SELECT posts.post_id, ' +
'COALESCE( likes.cnt, 0 ) AS like_count ,' +
'COALESCE( comments.cnt, 0 ) AS comment_count ,' +
'COALESCE( shares.cnt, 0 ) AS share_count ' +
'FROM posts ' +
'LEFT JOIN ( SELECT post_id, COUNT(*) AS cnt FROM likes GROUP BY post_id ) likes ON posts.post_id = likes.post_id ' +
'LEFT JOIN ( SELECT post_id, COUNT(*) AS cnt FROM comments GROUP BY post_id ) comments ON posts.post_id = comments.post_id ' +
'LEFT JOIN ( SELECT post_id, COUNT(*) AS cnt FROM shares GROUP BY post_id ) shares ON posts.post_id = shares.post_id ' +
'WHERE posts.post_id = $1',
[post.post_id],
(error, results) => {
if (error) {
console.log(error);
return res.json({'Error': error.detail});
}
const countQuery = results.rows[0];
// final response once all above queries are done, i dont account for thread comments in comment count rn, later problem
return {
postId: post.post_id,
userHandle: userHandle,
userImageUrl: userImageUrl,
postQuestion: post.post_question,
imageUrl: post.post_image_url,
postDescription: post.post_description,
votingOptions: Object.keys(post.voting_options),
voted: voted,
userVoteOption: userVoteOption,
liked: liked,
votingOptionsDictionary: votingOptionsDictionary,
voteStat: voteCount,
likeCount: parseInt(countQuery.like_count),
shareCount: parseInt(countQuery.share_count),
commentCount: parseInt(countQuery.comment_count),
createdAt: post.created_at
};
});
});
});
});
});
const postData = await Promise.all(promises);
return res.json(postData);
}
catch(e){
return res.json(e)
}
}
I'm trying to return an array of the postData for each post. For some reason it keeps on printing null for these objects because the return res.json is somehow running before the promises are even done. Any help is appreciated.
I had this problem before and used the same code, but it didn't work for this one for some reason.
回答1:
You're still not using promises but pass callbacks to query
. You cannot return
from those, and they won't be awaited by Promise.all
. You are looking for
async function returnPostData(req, res, initialPostsQueryArray) {
try{
const promises = initialPostsQueryArray.map( async (post) => {
const voteCount = sumValues(post.voting_options);
const results = await pool.query(
'SELECT userhandle, image_url FROM users WHERE id = $1 ',
[post.user_id],
]);
const userPostquery = results.rows[0];
const userHandle = userPostQuery.userhandle;
const userImageUrl = userPostQuery.image_url;
const {rows: likes } = await pool.query(
'SELECT EXISTS( SELECT 1 FROM likes WHERE user_id = $1 AND post_id = $2)',
[req.user.userId, post.post_id],
);
// if the user like exists, set liked = true
const liked = likes[0].exists;
const {rows: votes} = await pool.query(
'SELECT EXISTS( SELECT 1 FROM votes WHERE user_id = $1 AND post_id = $2)',
[req.user.userId, post.post_id]
);
// if the user vote exists, set voted = true and query for what they voted for
const voted = votes[0].exists;
if (voted) {
votingOptionsDictionary = post.voting_options;
const { rows } = await pool.query(
'SELECT voting_option FROM votes WHERE user_id = $1 AND post_id = $2',
[req.user.userId, post.post_id]
);
userVoteOption = rows[0].voting_option;
}
// i dont need voteCount here because that is calculated after the first query, this gets all the counts of the posts
const {rows: posts } = await pool.query(
`SELECT
posts.post_id,
COALESCE( likes.cnt, 0 ) AS like_count,
COALESCE( comments.cnt, 0 ) AS comment_count,
COALESCE( shares.cnt, 0 ) AS share_count
FROM posts
LEFT JOIN (
SELECT post_id, COUNT(*) AS cnt
FROM likes
GROUP BY post_id
) likes ON posts.post_id = likes.post_id
LEFT JOIN (
SELECT post_id, COUNT(*) AS cnt
FROM comments
GROUP BY post_id
) comments ON posts.post_id = comments.post_id
LEFT JOIN (
SELECT post_id, COUNT(*) AS cnt
FROM shares
GROUP BY post_id
) shares ON posts.post_id = shares.post_id
WHERE posts.post_id = $1`,
[post.post_id],
);
const countQuery = posts[0];
// final response once all above queries are done, i dont account for thread comments in comment count rn, later problem
return {
postId: post.post_id,
userHandle: userHandle,
userImageUrl: userImageUrl,
postQuestion: post.post_question,
imageUrl: post.post_image_url,
postDescription: post.post_description,
votingOptions: Object.keys(post.voting_options),
voted: voted,
userVoteOption: userVoteOption,
liked: liked,
votingOptionsDictionary: votingOptionsDictionary,
voteStat: voteCount,
likeCount: parseInt(countQuery.like_count),
shareCount: parseInt(countQuery.share_count),
commentCount: parseInt(countQuery.comment_count),
createdAt: post.created_at
};
});
const postData = await Promise.all(promises);
return res.json(postData);
}
catch(e){
return res.json(e)
}
}
来源:https://stackoverflow.com/questions/65587575/multiple-queries-in-a-map-function