【问题标题】:Process 1 loop at a time containing async function一次处理 1 个包含异步函数的循环
【发布时间】:2018-10-28 23:31:14
【问题描述】:

我有一个程序需要迭代数百个文件夹。每个文件夹都包含一个我读取的主 xml 文件,然后循环遍历文件中的每个元素。我的过程是读取目录并获取文件夹,然后对文件夹执行 for 循环,然后将主文件中的每个元素放入一个数组并执行 forEach。在 forEach 内部有 2 个异步函数被调用。两者都是 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);
});

【问题讨论】:

    标签: javascript node.js loops asynchronous


    【解决方案1】:

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

    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();

    【讨论】:

    • 这段代码仍然有同样的问题。 processNextFolder 在 mongdb 调用运行之前被调用,所以它仍然只是排队,直到内存不足。
    • @RUEMACHINE 这是您的实施问题,而不是我建议的解决方案。您需要确保在上次文件夹操作的“已完成”回调中调用了 processNextFolder()
    猜你喜欢
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多