[英]Handle queries inside loop in node.js
在下面的代码中,val 变量值由于异步行为而不断变化并产生意外的输出,即在第一个循环的连接查询完成之前,var 变量根据第二个循环并产生错误的输出。在循环中处理查询的最佳方法是什么避免由异步性质引起的特质。
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[j];//some manipulation of someArr[j] (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); }
JavaScript 是一种单线程语言,这意味着一次只能执行一个任务。 当 JavaScript 解释器最初执行代码时,它默认首先进入全局执行上下文。 从这一点开始,每次调用函数都会导致创建一个新的执行上下文。
对于每个执行上下文,都有一个与之耦合的作用域链。 作用域链包含执行堆栈中每个执行上下文的变量对象。 它用于确定变量访问和标识符解析。
匿名函数帮助我们创建一个新的作用域“阻塞” tVal
的值,因为当执行时,一个新的scope
被添加到包含val
值的scope chain
中。 这个新的scope
是父母的孩子scope
在至极的for loop
执行,当循环下去tVal
变化,但val
包含在子scope
,距离变化的安全。
在执行查询中使用 loop & 的最佳标准方法是使用async.eachSeries 。
因此,使用async.eachSeries它将一个接一个地执行,一旦 foreach 完成,您就可以使用回调。
参考: 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
});
})
尝试“让”而不是“var”这可能会奏效
var output = [];
for ( let 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
}
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.