节点 mysql2 sub-promise / 子查询并将结果附加到 json object
Node mysql2 sub-promise / subquery and append results to json object
所以我令人费解的标题可能解释了为什么我很难找到答案。
我正在 return 是 JSON object 的节点中编写 REST API。我有一个包含两个表的数据库,'Adverts' 和 'Photos' 每个广告都有很多照片。我正在使用 mysql2 和 promises。
我想 return 一个 object 和一组广告(这有效),每个广告都包含一组照片。我通过获取所有广告然后将照片数据附加到 object.
来做到这一点
如果我在我的 getAdvertPhotos 函数中 return 一些硬编码数据,例如
var hard_coded = { count: 2, pics: [{ id:1, url:'pic1.jpg'},{ id:2, url:'pic2.jpg'}]};
return hard_coded;
然后一切都按我想要的方式运行,所以我很确定我的问题是调用 .getAll 的响应发生在数据库命中以获取照片之前。但是我不知道如何等待(await?)响应直到所有查询都完成。
我在数据库中确实有一个连接两个表的视图,因此所有结果都通过一个查询而不是两个查询获得,但随后我得到重复的广告详细信息行,具体取决于它有多少张照片,我完全理解数据库级别,因此可能有更好的方法将此结果处理为 object?
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"
}
]
}
}
]
}
到"await"一个不使用"await"关键字的承诺,你只需要return它。那么您的代码将如下所示:
'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
});
}
);
};
未测试。
所以我令人费解的标题可能解释了为什么我很难找到答案。
我正在 return 是 JSON object 的节点中编写 REST API。我有一个包含两个表的数据库,'Adverts' 和 'Photos' 每个广告都有很多照片。我正在使用 mysql2 和 promises。
我想 return 一个 object 和一组广告(这有效),每个广告都包含一组照片。我通过获取所有广告然后将照片数据附加到 object.
来做到这一点如果我在我的 getAdvertPhotos 函数中 return 一些硬编码数据,例如
var hard_coded = { count: 2, pics: [{ id:1, url:'pic1.jpg'},{ id:2, url:'pic2.jpg'}]};
return hard_coded;
然后一切都按我想要的方式运行,所以我很确定我的问题是调用 .getAll 的响应发生在数据库命中以获取照片之前。但是我不知道如何等待(await?)响应直到所有查询都完成。
我在数据库中确实有一个连接两个表的视图,因此所有结果都通过一个查询而不是两个查询获得,但随后我得到重复的广告详细信息行,具体取决于它有多少张照片,我完全理解数据库级别,因此可能有更好的方法将此结果处理为 object?
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"
}
]
}
}
]
}
到"await"一个不使用"await"关键字的承诺,你只需要return它。那么您的代码将如下所示:
'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
});
}
);
};
未测试。