nodejs如何让循环等待直到运行下一个循环实例

时间:2017-05-30 12:49:20

标签: node.js mongodb google-bigquery async.js

我正在使用带有mongodb和bigquery的nodejs。

因为看起来bigquery每个命令只允许10k次插入。

所以我计算了主查询,并循环到10k的页数。

我得到500k的计数查询,所以50页或500循环。

如何循环等待直到运行循环的下一页?

代码:

(eval-after-load 'hideshow
 '(progn
   (global-set-key (kbd "C-+") 'hs-toggle-hiding)))

3 个答案:

答案 0 :(得分:2)

我认为for循环对于这种情况不是一个好的解决方案,你可以使用这样的递归调用循环:

function performQuery(queryIndex) {
    if( queryIndex >= limit ) return;

    db.exec('query', function(err, db_result) {
        // your code
        performQuery(queryIndex+1);
    })
}
performQuery(0);

答案 1 :(得分:1)

我可能会用async.eachSeries替换for循环,这样就可以决定循环的下一次迭代发生的时间,并且由于async.eachSeries一次只运行1次操作,所以你不会遇到同样的错误

修改

阅读完代码后,我认为async.timesSeries(从我的评论中更正,async.timesSeries是正确的选项)是一个更好的选择。这是一个例子:

async.timesSeries(pages, function(page, next)
{
    var skip = page * limit;
    // ... the rest of your code here

    // when you want the next iteration to start, simply call:
    next();
    /*
    which will tell async that the current iteration is complete, 
    and it can do the next one. You can pass 2 parameters to next,
    the first parameter is an error, and if error is not null it will
    immediately call the function below, and the second parameter is an
    item you can pass that will be added to an object which will be sent
    as the second parameter in the function below
    */
},
function(err, coll)
{
    /*
    this function will get called if there's an error
    or when all iterations are completed
    */
});

以上代码将替换您的for循环

答案 2 :(得分:0)

如果您不想使用递归承诺,并且事先知道项目数,您可以这样做:

// Create a "skip" array (there is certainly a nicer way to do it, with a modulo)
var skips = []; 
for(var page=0;page<pages;page++){
    skips.push(page * limit);
}

// Put your mongoDB read and write code in a function
// (that takes skip in entry and returns an array of documents)
var myMongoDBFunc = function (skip) {
    var documents = [];

    db.collection('my_table')
       .find(query)
       .limit(limit)
       .limit(skip)
       .toArray(function(err, db_results) { 
           ...
       });
   ...
   return documents;
}

// And call it with async.concatSeries that will concatenate the results (documents)
async.concatSeries(skips, myMongoDbFunc, function(err, documents) {
    // Will be called at the end
});

如果您想并行优化并运行所有查询,只需将concatSeries替换为concat(但订单不会得到保证)。

如果你不关心退回的文件(显然你只是想写点什么),也许你可以使用async.seriesasync.parallel(自己检查,我不会&#39特别知道async)。