在node.js中循环处理查询

在下面的代码中,valvariables值因asynchronous行为而不断变化,并产生意外的输出,即在第一个循环的连接查询完成之前,根据第二个循环的varvariables并产生错误的输出。在循环中处理查询的最佳方式是什么这样可以避免asynchronous性造成的特殊情况。

var output = []; for ( var j = 0; j < someArr.length ; j++ ) { val = someArr[j];//some manipulation of someArr[j] connection.query( "select id from someTable where someCol = ?",val, function(err, rows, fields) { if ( err ) { console.log( err ); } else { output.push( rows[0].someVal );//push query output to this variable } }); } 

console.log(output); //应该包含所有查询的输出。

只需使用闭包生成一个临时范围

 var output; for ( var j = 0; j < someArr.length ; j++ ) { tVal = someArr[i];//some manipulation of someArr[i] (function(val){ connection.query( "select id from someTable where someCol = ?",val, function(err, rows, fields) { if ( err ) { console.log( err ); } else { output.push( rows[0].someVal );//push query output to this variable } }); })(tVal); } 

在那个执行查询中使用循环和最好的标准方法是使用async.eachSeries

所以使用async.eachSeries它将一个接一个地执行,一旦完成,你可以使用callback。

参考: http : //caolan.github.io/async/docs.html#eachSeries

 var async = require('async'); var output = []; connection.query('SELECT * FROM tablename LIMIT 10',function(error,results,filelds){ if(error) throw err; async.eachSeries(results,function(data,callback){ // It will be executed one by one //Here it will be wait query execute. It will work like synchronous connection.query('SELECT * FROM tablename where id = 1',function(error,results1,filelds){ if(error) throw err; output.push(results1[0].id) callback(); }); }, function(err, results) { console.log(output); // Output will the value that you have inserted in array, once for loop completed ex . 1,2,3,4,5,6,7,8,9 }); })