Node.js + socket.io + MySQL 语法更正

Node.js + socket.io + MySQL correction of syntax

考虑到我的 server.js 看起来差不多是这样。只需将相关部分发送给您即可。我没有从查询中收到任何东西,我在数据库中有数据,并且 "sendNotification" 是由客户端中的 jQuery 函数触发的。一切正常,因为 var notis = []; returns 一个空值,显示为响应。我知道我必须调试 SQL,这就是我要做的,但无论如何我想确定其他事情。所以我的问题是:

1) 考虑到这种异步行为,node.js 的语法是否正确? (我还是不明白)

2) 查询总是应该在 "io.sockets.on('connection')" 部分内?

connection = mysql.createConnection({
host: 'localhost',
user: '',
password: "",
database: 'table' //put your database name
}),

...

connection.connect(function(err) {
// connected! (unless `err` is set)
console.log(err);
});

…

var sqlquery = function(uID,vs){
var notis = [];
connection.query("SELECT * FROM notification WHERE kid = ? AND v = ? ORDER BY id DESC",[uID,vs])
.on("result", function (data){
    return notis.push(data);
});
};


 io.sockets.on('connection', function(socket) {
 ...
socket.on("sendNotification", function(data) {
    var roomBName = data.room_name.replace("room-",""),
        found = [];

        var roomSelected = _.find(rooms, function (room) { return room.id == roomBName });


        for (var person in people) {
            for (var i = 0, numAttending = roomSelected.peopleAttending.length; i < numAttending; i++) {

                if (people[person].name == roomSelected.peopleAttending[i]) {

                    found.push(person);
                }
            }
        }

        for (var i = 0, numFound = found.length; i < numFound; i++) {


            **result = sqlquery(9,2);**


            io.to(found[i]).emit('notification', result);
        };

});

您的 sqlquery() 函数不会完成任何有用的事情。因为 connection.query() 是异步的,这意味着它会在 sqlquery() 完成后的某个时间提供响应。

node.js 中使用异步结果的唯一方法是在提供它的回调中实际使用它。您不只是将它填充到其他变量中并期望结果在其他代码中为您提供。相反,您可以在回调中使用它,或者从回调中调用其他函数并将数据传递给它。

这是一种方法,您可以更改 sqlquery() 函数:

var sqlquery = function(uID, vs, callback){
    connection.query("SELECT * FROM notification WHERE kid = ? AND v = ? ORDER BY id DESC",[uID,vs])
    .on("result", function (data){
        callback(null, data);
    });
    // need to add error handling here if the query returns an error
    // by calling callback(err)
};

然后,您可以像这样使用 sqlquery 函数:

    found.forEach(function(person, index) {
        sqlquery(..., function(err, result) {
            if (err) {
                // handle an error here
            } else {
                io.to(person).emit('notification', result);
            }
        });
    });

而且,看起来您可能在其他地方也有类似的异步问题,例如 connection.connect()

除了@jfriend00,这可以通过新的 ES6 功能来完成 Promise :

var sqlquery = function(uID, vs){
    return new Promise(function(resolve, reject){
        connection.query("SELECT * FROM notification WHERE kid = ? AND v = ? ORDER BY id DESC",[uID,vs])
        .on("result", function (data){
            resolve(data);
        });
    });
};

现在您可以像这样使用它了:

found.forEach(function(person, index) {
    sqlquery(...)
    .then(function(result){
        io.to(person).emit('notification', result);
    });
});