node.js + for循环+查询执行

时间:2014-04-21 11:15:42

标签: javascript node.js

我正在执行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循环中执行的所有查询之后打印数组。但现在它在阵列之前的打印已经填充。帮我解决这个问题。提前谢谢..

1 个答案:

答案 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;