.map 函数中的多个查询 [英] Multiple queries in a .map function

查看:46
本文介绍了.map 函数中的多个查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我正在尝试为每个帖子返回一个 postData 数组.出于某种原因,它会继续为这些对象打印 null,因为返回 res.json 甚至在承诺完成之前就以某种方式运行.任何帮助表示赞赏.

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.

推荐答案

您仍然没有使用 Promise,而是将回调传递给 query.你不能从那些中return,而且Promise.all 不会等待它们.您正在寻找

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

这篇关于.map 函数中的多个查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆