json - Node mysql2子 promise /子查询并将结果附加到json对象

标签 json node.js promise mysql2

所以我的复杂标题可以解释为什么我正在努力寻找答案。

我正在 Node 中编写一个返回 JSON 对象的 REST API。我有一个包含两个表的数据库,“广告”和“照片”,每个广告有很多照片。我正在使用带有 Promise 的 mysql2。

我想返回一个带有广告数组的对象(这有效),并且每个广告都包含一组照片。我通过获取所有广告然后将照片数据附加到对象来做到这一点。

如果我在 getAdvertPhotos 函数中返回一些硬编码数据,例如

var hard_coded = { count: 2, pics: [{ id:1, url:'pic1.jpg'},{ id:2, url:'pic2.jpg'}]};

return hard_coded;

然后一切都按照我想要的方式工作,所以我非常确定我的问题是对 .getAll 的调用的响应发生在数据库命中以完成照片之前。但我不知道如何等待(等待?)响应,直到所有查询完成。

我在数据库中有一个 View 连接两个表,因此所有结果都在一个查询中而不是两个查询中通过,但随后我得到了重复的广告详细信息行,具体取决于它有多少张照片,我在数据库级别完全理解这一点,因此可能有一种更好的方法来将此结果处理为对象?

exports.getAll = (req, res, next) => {
    db.selectAll('adverts', 'id', 'desc')
    .then(
        adverts => {
            adverts.map(advert => {
                advert.photos = getAdvertPhotos(advert.id);
            });

            res.status(200).json({
                message: 'GET to /adverts',
                count: adverts.length,
                adverts: adverts
            });
        }
    )
    .catch(
        error => {
            res.status(500).json({
                message: 'GET to /adverts',
                error: error
            });
        }
    );
};

function getAdvertPhotos(id){
    db.selectAllById('photos', 'advert_id', id, 'id', 'desc')
    .then(
        photos => {
            var json = {
                count: photos.length,
                pics: photos.map(photo => {
                    return {
                        id: photo.id,
                        request: {
                            type: 'GET',
                            url: photo.url
                        }
                    };
                })
            };

            return json;
        }
    )
    .catch(
        error => {
            console.log(error);
            }
    );
}

这是我希望看到的结果的示例

{
    "message": "GET to /adverts",
    "count": 3,
    "adverts": [
        {
            "id": 1,
            "title": "Title 1",
            "price": 123,
            "description": "A description 1",
            "photos": {
                "count": 2,
                "pics": [
                    {
                        "id": 1,
                        "url": "pic1.jpg"
                    },
                    {
                        "id": 2,
                        "url": "pic2.jpg"
                    }
                ]
            }
        },
        {
            "id": 2,
            "title": "Title 2",
            "price": 456,
            "description": "A description 2",
            "photos": {
                "count": 2,
                "pics": [
                    {
                        "id": 1,
                        "url": "pic3.jpg"
                    },
                    {
                        "id": 2,
                        "url": "pic4.jpg"
                    }
                ]
            }
        },
        {
            "id": 3,
            "title": "Title 3",
            "price": 789,
            "description": "A description 3",
            "photos": {
                "count": 2,
                "pics": [
                    {
                        "id": 1,
                        "url": "pic5.jpg"
                    },
                    {
                        "id": 2,
                        "url": "pic6.jpg"
                    }
                ]
            }
        }
    ]
}

最佳答案

要“等待” promise 而不使用“await”关键字,您只需返回它即可。那么你的代码将如下所示:

'use strict';

function getAdvertPhotos(id){
    return db.selectAllById('photos', 'advert_id', id, 'id', 'desc')
    .then(
        photos => {
            var json = {
                count: photos.length,
                pics: photos.map(photo => {
                    return {
                        id: photo.id,
                        request: {
                            type: 'GET',
                            url: photo.url
                        }
                    };
                })
            };

            return json;
        }
    )
    .catch(
        error => {
            console.log(error);
            }
    );
}

exports.getAll = (req, res, next) => {
    return db.selectAll('adverts', 'id', 'desc')
    .then(
        adverts => {

            const photoJobs = adverts.map(advert => {

                return getAdvertPhotos(advert.id).then(photos => ({
                    advertId: advert.id,
                    photos
                }));
            });


            return Promise.all(photoJobs).then(results => {

                return adverts.map(advert => {
                    const res = results.find(r => r.advertId === advert.id);
                    advert.photos = res ? res.photos : [];
                    return advert;
                });
            })
            .then(adverts => {

                return res.status(200).json({
                    message: 'GET to /adverts',
                    count: adverts.length,
                    adverts: adverts
                });
            });
        }
    )
    .catch(
        error => {
            res.status(500).json({
                message: 'GET to /adverts',
                error: error
            });
        }
    );
};

未经测试。

关于json - Node mysql2子 promise /子查询并将结果附加到json对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51753117/

相关文章:

node.js - 使用 NodeJS Promise 查询 MongoDB

javascript - 搜索不同属性时 Json 数据的正确布局

json - 使用HTML和AngularJS获取和显示JSON数据字段

node.js - 我收到以下错误 - NPM 错误 : debug module is not working

javascript - 如何按模式查找但排除条件列表

json - ReactJS:JSON 文件是从本地主机而不是项目目录获取的

javascript - 同时显示两个独立加载且加载时间不同的元素

Java Http 请求 JSON 和响应处理

java - 带有附加 url 参数的 Restful 帖子?

javascript - Angular JS $http Promise 的行为是否像真正的 $q Promise 一样?