socket.io和节点回调函数不起作用
问题描述:
我在socket.io中抓取异步回调和变量存储非常困难。我希望回调函数中的代码在所有查询完成后执行。但是,我不知道在哪里放置callback()方法调用,以便在所有事情完成后执行。我将不胜感激任何和所有的帮助。socket.io和节点回调函数不起作用
//The code below queries a database and stores the information in a json object.
var mysql = require('mysql')
var io = require('socket.io').listen(3000)
var db = mysql.createConnection({
host: '',
user: '',
password: '',
database: '',
port: 3306,
})
db.connect(function(err){
if (err) console.log(err)
})
console.log(1);
io.sockets.on('connection', function(socket){
socket.on('key', function(value){//client side has a onclick() function that emits 'key'
console.log(2);
var total = {};
var personalTable = []
var liwcTable = []
var id = value;
help(total, function(total) {
console.log(4);
console.log("total = " + JSON.stringify(total));
socket.emit('total', total);/emits to client
});
function help(total, callback) {
console.log(3);
db.query('SELECT * FROM `a` WHERE `userId` =' + id)
.on('result', function(data){
liwcTable.push(data)
})
.on('end', function(){
total["initial liwcTable"] = liwcTable;
})
db.query('SELECT * FROM `b` WHERE `userId` =' + id)
.on('result', function(data){
personalTable.push(data)
})
.on('end', function(){
total['personalTable'] = personalTable;
})
callback(total)//needs to be executed after the queries are done.
}
})
})
代码在查询有机会完成之前进入回调方法。我也不明白,当查询回调的范围有限时,我可以如何更新我的json对象“total”。
答
您有许多解决方案可以在所有想要的操作后触发回调。 例如,您可以创建一个在每个查询后调用的单例,这将触发最终的回调。
function help(total, callback) {
var nbEndedQueries = 0,
amountOfQueries = 2;//nb of linked queries
function singleton() {
//increments the nbEndedQueries variable and tests if the max is reached
if(++nbEndedQueries >= amountOfQueries)
callback();
}
db.query(... //query calling)
.on('result', ...//some behaviours
singleton();
)
db.query(... //query calling)
.on('result', ...//some behaviours
singleton();
)
//...
}
另一种解决方案是使用承诺。 像Q或在ECMA6填充工具许多模块为您提供这个功能,它是完全以真棒
与ecm6承诺填充工具样品
//promisification of the query method
function query(string) {
return new Promise(function(resolve, reject) {
db.query(string)
.on('result', resolve)
//i supposed an error event exist
.on('error', reject);
})
}
//and now the usage
function help() {
//basic method
//first query calling
query('your query string')
.then(function(result) {
//behaviour
//second query calling, the result will send to the next 'then' statement
return query('second query');
})
.then(function() {
//behaviour
//at this point, all queries are finished
callback() ;
});
}
//parallelized sample
function help() {
//starts all queries and trigger the then if all succeeds
Promise.all([query('your query string'), query('second query')])
.then(function(results/*array of results*/) {
//behaviour
callback();
})
}