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