进程1循环包含异步函数

时间:2018-05-18 13:45:36

标签: javascript node.js loops asynchronous

我有一个程序,我需要迭代几百个文件夹。每个文件夹都包含一个我读取的主xml文件,然后循环遍历文件中的每个元素。我的过程是读取目录并获取文件夹,然后对文件夹执行for循环,然后将主文件中的每个元素放入数组并执行forEach。在forEach中,有两个被调用的异步函数。两者都是mongoDB查询。第一个是进行查找以获取每个元素的数据,然后在最后我对mongoDB进行更新。

我遇到的问题是因为异步函数正在排队并等待循环在执行之前完成,所以进程内存不足。在这种情况下,可能有大约100,000个元素,因此处理起来太多了。

我想弄清楚的是,是否有更好的方法可以做到这一点,或者是否有办法在进入下一个文件夹之前完全处理单个文件夹。

这是代码结构的简化示例。

fs.readdir(dirname + 'folders', function(err, folders) {
for (var i = 0; i < folders.length; i++) {
    var resources = resources;
    resources.forEach(function(doc) {
        //do lookup in mongodb
        getStandardsArray(doc, function(standardsArray, origItem) {
            //In callback update item in mongodb
            db.collection(collection).update( {"id": id}, origItem, { upsert: true}, function(err, numberAffected) {
                if (err) {
                    console.log(err);
                }
            });
        });
    });
}
}

getStandardsArray = function(item, standards, callback) {
sharedDb.collection("standards").findOne({"id": formatGUID(standards[i])}, function(err, doc) {
    callback(standardsArray, item);
});

1 个答案:

答案 0 :(得分:1)

您可以使用递归函数编写自己的循环代码;这样你可以等到所有回调/承诺都解决后再转到下一个文件夹:

&#13;
&#13;
const folders = ["A", "B", "C", "D", "E"];
var folderIndex = -1;

function processNextFolder() {
  if (++folderIndex === folders.length) return; // done
  new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(`Folder ${folders[folderIndex]} processed`);
      resolve();
    }, 1000);
  }).then(() => {
    processNextFolder();
  })
}

console.log("Starting...");
processNextFolder();
&#13;
&#13;
&#13;