如何在继续之前等待Javascript同步循环内的异步回调完成

时间:2017-06-30 00:40:39

标签: javascript node.js callback

我知道我用过#34;等等#34;和" asyncronous"同一句话中的词语没有意义。但我想知道是否有人可以建议我解决我的问题。

我有for循环,它运行在mongodb返回的docs数组上。现在,根据一些逻辑,我需要删除某些文档。只有在我完成删除文档后,我才能调用我的下一个方法。看起来像下面这样:

mymongodbconnection.find({}).toArray(function(err, documents) {
if (!err && documents.length !== 0) {
  documents.forEach(function(document) {

      if( someCheckPerformed(document)){
        console.log('keeping');
      }else{
        console.log('removing');
mymongodbconnection.remove({_id:document._id},fun(err,result){});
      }
  });

 notifyAdminAboutChange();
} else {
  logger.warn('No existing UA docs to filter');
}
});

现在,正如您所看到的,我需要调用notifyAdminAboutChange();只有在for循环完成迭代所有文档并删除了需要删除的文档之后。

我的问题:

  1. 我可以阻止for循环执行以等待删除完成吗?
  2. 如果1不可能,那么我该如何实现这个用例?

2 个答案:

答案 0 :(得分:0)

我不知道任何可以轻易地填充现有结构的JS轻松,但如果你重新安排一点并让你的思想开放于递归解决方案,你可能会达到你想要的结果:

coll.find({}).toArray((err, docs)=> {
    (function checkDoc(i){
        if(i >= docs.length) return;
        else if(pred(docs[i])) checkDoc(i + 1);
        else coll.remove({_id: docs[i]._id}, _=> checkDoc(i + 1));
    })(0);
})

这样,文档将按顺序检查,只有在完成当前文档的处理时才会处理下一个文档。

demo

答案 1 :(得分:0)

使用promises - 为每个要删除的文档创建一个,然后在调用函数之前等待它们全部解析(使用Promise.all)。

mongodBCollectionInstance.find({}).toArray(function(err, documents) {
  if (!err && documents.length !== 0) {
    var promises = [];

    documents.forEach(function(document) {
      if( someCheckPerformed(document)){
        console.log('keeping');
      }else{
        console.log('removing');
        promises.push(new Promise(function (fulfill, reject){
          mongodBCollectionInstance.remove(
            {_id:document._id},
            function (err, result) {
              fulfill();
            });
        }))
      }
    });
    Promise.all(promises).then(function () {
      notifyAdminAboutChange();
    });
  } else {
    logger.warn('No existing UA docs to filter');
  }
});