Обрабатывать 1 цикл за раз, содержащий асинхронную функцию - PullRequest
0 голосов
/ 18 мая 2018

У меня есть программа, в которой мне нужно перебрать несколько сотен папок.Каждая папка содержит основной 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);
});

1 Ответ

0 голосов
/ 18 мая 2018

Вы можете кодировать свой собственный цикл, используя рекурсивную функцию;Таким образом, вы можете подождать, пока все обратные вызовы / обещания будут разрешены, прежде чем перейти к следующей папке:

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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...