问题描述
我正在做一个私人项目,以创建我参加的音乐会的清单。
我有这些表:
- vi_concert(ID,标题,日期,位置)
- vi_artist(ID,名称,永久性)
- vi_location(ID,名称,永久性)
- vi_artist_concert(artist_id,concert_id)
我做了两个查询。 一个用于演唱会信息,第二个用于排队信息:
router.get('/:id', (req, res) => {
var output = [];
// Get Concert Information
let concert = `SELECT c.date, c.title, l.name AS location
FROM vi_concert c
INNER JOIN vi_location l ON c.location=l.id
WHERE c.id = '${req.params.id}'`;
db.query( concert, (err, result) => {
if ( err ) throw err;
output.push(result);
});
let lineup = `SELECT a.name, a.perma
FROM vi_artist_concert ac
JOIN vi_artist a ON a.id = ac.artist_id
JOIN vi_concert c ON c.id = ac.concert_id
WHERE ac.concert_id = '${req.params.id}'`;
db.query( lineup, (err, result) => {
if ( err ) throw err;
output.push(result);
});
res.send(JSON.stringify(output));
});
当我调用URL localhost:3000 / concerts / 1时,我得到以下信息:
[ ]
但是我想要这样的东西:
[
"concert": {
"date": "2019-02-16 19:30:00",
"title": "Fancy title",
"location": "Fancy location"
},
"lineup": [
{
"name": "Band 1",
"perma": "band-1"
},
{
"name": "Band 234",
"perma": "band-234"
}
]
]
1楼
Javascript是异步的 。
这意味着您的代码无需等待数据库查询结束就发送JSON.stringify(output)
。
您将必须:
- 进行第一个查询, 然后进行第二个查询, 然后发送输出或
- 并行执行第一个和第二个查询, 然后发送输出
没有任何其他库的第一种方法:
router.get('/:id', (req, res) => {
var output = [];
// Get Concert Information
let concert = `SELECT c.date, c.title, l.name AS location
FROM vi_concert c
INNER JOIN vi_location l ON c.location=l.id
WHERE c.id = '${req.params.id}'`;
let lineup = `SELECT a.name, a.perma
FROM vi_artist_concert ac
JOIN vi_artist a ON a.id = ac.artist_id
JOIN vi_concert c ON c.id = ac.concert_id
WHERE ac.concert_id = '${req.params.id}'`;
db.query( concert, (err, result) => {
if ( err ) throw err;
output.push(result);
db.query( lineup, (err2, result2) => {
if ( err2 ) throw err2;
output.push(result2);
res.send(JSON.stringify(output));
});
});
});
async
库的第二种方法:
var async = require('async');
router.get('/:id', (req, res) => {
var output = [];
// Get Concert Information
let concert = `SELECT c.date, c.title, l.name AS location
FROM vi_concert c
INNER JOIN vi_location l ON c.location=l.id
WHERE c.id = '${req.params.id}'`;
let lineup = `SELECT a.name, a.perma
FROM vi_artist_concert ac
JOIN vi_artist a ON a.id = ac.artist_id
JOIN vi_concert c ON c.id = ac.concert_id
WHERE ac.concert_id = '${req.params.id}'`;
async.parallel([
function(callback){
db.query( concert, (err, result) => {
if ( err ) return callback(err);
output.push(result);
});
}, function(callback){
db.query( lineup, (err, result) => {
if ( err ) return callback(err);
output.push(result);
});
}
], function(err){
if(err)
throw err;
res.send(JSON.stringify(output));
})
});
如果您的数据库驱动程序支持promise,那么您也可以使用promise ,但是我会根据您的时间允许您使用它们。
2楼
在发送响应之前,您无需等待数据库中的记录。
db.query()
方法是一个异步操作,只有在调用回调函数后才能使用。
您可以在代码中进行更改以使其起作用,是将查询嵌套在另一个回调的内部,并仅在获得db结果后才发送响应。
router.get('/:id', (req, res) => {
var output = [];
// Get Concert Information
let concert = `SELECT c.date, c.title, l.name AS location
FROM vi_concert c
INNER JOIN vi_location l ON c.location=l.id
WHERE c.id = '${req.params.id}'`;
db.query( concert, (err, result) => {
if ( err ) throw err;
output.push(result);
// Nesting the second query in the first query callback
let lineup = `SELECT a.name, a.perma
FROM vi_artist_concert ac
JOIN vi_artist a ON a.id = ac.artist_id
JOIN vi_concert c ON c.id = ac.concert_id
WHERE ac.concert_id = '${req.params.id}'`;
db.query( lineup, (err, result) => {
if ( err ) throw err;
output.push(result);
// Sending the response to browser only after getting the second result
res.send(JSON.stringify(output));
});
});
});
替代方法是使用 。
较新版本的Node.js支持 / 语法。