Использование Async с рекурсией в узле для возврата всех результатов - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть база данных, в которой родительские записи могут иметь неограниченное количество детей. Следующие упрощенные записи иллюстрируют:

id: 0, родитель: null
id: 1, родитель: 0
id: 2, родитель: 0
id: 3, родитель: 2

Я уже несколько недель пытаюсь написать рекурсивную функцию в node / express, которая генерирует объект javascript, представляющий это дерево записей и НЕ возвращающийся до его завершения. Я могу сделать это без проблем, пока я включаю тайм-аут, но, очевидно, это неоптимально.

Это моя самая последняя попытка:

var getChildren = function (parent, callback) {
    const query = "SELECT ID, ParentID, NULL AS Children FROM myTable WHERE "ParentID = '" + parent.ID + "'";
    db.doQuery (query, function (err, results) {
        if(err) {
            callback (true);
        } else {
            if (results.length == 0) callback (false, parent);  // We didn't find any children so we end the recursion
            parent.Children = results;  // Each time we get a result set we need to add that set to our Children property
            // Iterate through our result set to find the next layer of children
            var i = 0;
            async.whilst (
                function () { return i < results.length },
                function (callback) {
                    i++;
                    getChildren(parent.Children[i - 1], function (err, results) {
                        if (err) callback (true);
                    })
                },
                callback (false, parent)
            );
        }
    })
}

Короче говоря, это рекурсивная процедура, которая читает все дочерние элементы как записи из базы данных. Он добавляет этот результирующий набор к свойству объекта «Дети», а затем выполняет итерацию по результирующему набору и для каждого рекурсивно вызывает себя, чтобы найти больше потомков этой записи. Возвращаемый в итоге JSON выглядит следующим образом:

{
      "ID": "000000000",
      "ParentID": null,
      "Children": [
        {
          "ID": "000000001",
          "ParentID": "000000000",
          "Children": null
        },
        {
          "ID": "000000002",
          "ParentID": "000000000",
          "Children": [
            {
              "ID": "000000003",
              "ParentID": "000000002",
              "Children": null
            }
          ]
        }
      ]
}

Как вы, вероятно, уже можете сказать, на самом деле происходит то, что приведенный выше код возвращает только первый уровень потомков, пока я не установлю таймаут в вызывающей функции. Я пробовал несколько асинхронных функций, я пытался подсчитывать тайм-ауты, я пытался переписать циклы с их собственными рекурсивными функциями с обратным вызовом, и я не могу на всю жизнь заставить это работать. Я знаю, что проблема в том, что я просто не могу обернуть голову вокруг некоторой асинхронной магии, которая поможет мне определить, когда реальная рекурсия полностью завершена, и обратный вызов вызывающей функции.

Это тот случай, когда мне нужно отслеживать уровни рекурсии, которые я вызвал, и затем считать их в обратном порядке, прежде чем я использую окончательный обратный вызов?

Любое понимание будет с благодарностью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...