我正在执行for循环,在for循环中我正在执行postgresql查询并将结果填充到数组中。但我无法预测执行流程。
我的代码:
var array =[];
for(var i = 0 ; i< latitude.length; i++){
client.query("SELECT value->>'xxxx' as xxxx_details FROM yyyyy WHERE ST_DWithin(ST_GeogFromText('SRID=4326;POINT ("+latitude[i]+" "+longitude[i]+")'), geography(the_geom), " + radius + ")", function(err, row, fields) {
array.push(row.rows[0]);
}
console.log("bbbbbbbbb=" +array);
我需要的是我希望在for循环中执行的所有查询之后打印数组。但现在它在阵列之前的打印已经填充。帮我解决这个问题。提前谢谢..
答案 0 :(得分:5)
原因是client.query是异步的,结果仅在回调中可用。
一个选项是async.js。好写when to use what here。
从该文章中,您可以为集合中的每个项目执行代码。因此,对于您的示例,您可以使用一组索引或foreach来构建一个sql查询语句数组,然后为每个查询执行一些。
如果查询是一组查询,那么类似于:
async.forEach(queries, function(query, callback) {
client.query(query, function(err, row, fields){
array.push(row.rows[0]);
callback(); // this signals async that you're done with this item
});
}, function(err) {
if (err) return next(err);
// all queries are done here
});
注意还有forLachLimit用于并行执行n和forEachSeries,其限制为1(顺序)。
编辑:
更好的选择是async / await,如果您使用typescript并编译为ES6 +并使用节点4+(具有生成器),则现在可以使用async / await。
我详细介绍了此sane node repo
来自该回购的片段显示等待循环中的异步调用。它保持异步,并且在完成之前不会进入下一行。这也有你想象的尝试/捕获处理的好处。
// await allows us to write linear code.
// makes it easy to also call async code in a loop
// offers easy error handling with try catch
var quotes: IQuote[];
var tries: number = 0;
while (true) {
try {
++tries;
// ASYNC/AWAIT
quotes = await this._store.find<IQuote>({});
break;
}
catch (err) {
if (tries == 3) { throw err; }
}
}
return quotes;