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);
});
});
考虑到我的 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);
});
});