将查询结果推入对象

时间:2019-02-13 16:40:10

标签: javascript mysql node.js

我正在处理一个私人项目,以创建我参加的音乐会的清单。

我有这些表:

  • vi_concert(ID,标题,日期,位置)
  • vi_artist(ID,名称,永久性内容)
  • vi_location(ID,名称,永久性内容)
  • vi_artist_concert(artist_id,concert_id)

我做了2个查询。一个用于演唱会信息,第二个用于排队信息:

struct_id = Encoding.ASCII.GetBytes("MQTC");

当我调用URL localhost:3000 / concerts / 1时,我得到以下信息:

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

但是我想要这样的东西:

[ ]

2 个答案:

答案 0 :(得分:0)

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 (承诺),但我会根据自己的时间让您使用Google。

答案 1 :(得分:0)

在发送响应之前,您不必等待数据库中的记录。
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));
        });
    });
});

一种替代方法是使用Promise s。
较新版本的Node.js支持async / await语法。