Как мне рекурсивно искать результаты в Firestore? - PullRequest
2 голосов
/ 07 февраля 2020

Я новичок в Node и Firebase.

В настоящее время я работаю над калькулятором крафта для игры и храню игровые предметы в Firebase. Некоторые элементы являются составными элементами, например:

1 Lumber Plank = 5 Logs

Исходя из таких требований, я структурировал все элементы как одну коллекцию под названием items в Firebase.

Журнал будет быть сохраненным как:

{
  "type": "basic",
  "name": "log"
}

В то время как планка пиломатериалов будет:

{
  "type": "composite",
  "name": "lumber plank",
  "materials": ["log"],
  "material_values": [5]
}

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

{
    "name": "board",
    "count": 1,
    "materials": [
        {
            "name": "lumber plank",
            "count": 1,
            "materials": [
                {
                    "name": "log",
                    "count": 5,
                    "materials": null
                }
            ]
        }
    ]
}

У меня проблемы с пониманием обратных вызовов при отладке, и этот фрагмент кода в настоящее время возвращает undefined, за которым следует log (я предполагаю, что это происходит от console.log в функции search).

async function search(item, result, count) {
    let calcItem = {
        name: item,
        count: count
    };

    db.collection("items")
        .doc(item)
        .get()
        .then(doc => {
            const data = doc.data();
            if (data.type === basic) {
                calcItem.materials = null;
                result.push(calcItem);
                return result;
            } else {
                let materials = data.materials;
                let materialsCount = data.material_values;
                calcItem.materials = [];
                for (let i = 0; i < materials.length; i++) {
                    console.log(materials[i]);
                    search(materials[i], calcItem.materials, materialsCount[i]);
                }
            }
        });
}

let item = "lumber plank";

search(item, [], 1).then(result => console.log(result));

Буду признателен за любые советы / подсказки здесь. Спасибо


После отзыва Дуга,

Я вроде как реорганизовал свой код на основе ваших комментариев, и я вижу некоторый прогресс.

function recursiveSearch(item, count, result) {
    let calcItem = {
        name: item,
        count: count
    };

    dbSearch(item).then(function (doc) {
        const data = doc.data();
        console.log(data);

        if (data.type === basic) {
            calcItem.materials = null;
            result.push(calcItem);
            return result;
        } else {
            let materials = data.materials;
            let materialsCount = data.material_values;
            calcItem.materials = [];
            for (let i = 0; i < materials.length; i++) {
                recursiveSearch(materials[i], materialsCount[i], calcItem.materials);
            }
        }
    });
}

function dbSearch(item) {
    return Promise.resolve(db.collection("items")
        .doc(item)
        .get()
        .then());
}

Журнал теперь выводит поиск правильно.

{
  material_values: [ 5 ],
  materials: [ 'log' ],
  name: 'lumber plank',
  type: 'composite'
}
{
  name: 'log',
  type: 'basic'
}

Однако, если я правильно понимаю, если я добавлю в эту строку, он все равно будет возвращать неопределенный, я прав?

console.log(recursiveSearch("lumber plank", 1, [])

Если да, то как мне на самом деле выйти из всей структуры элементов, завершив все рекурсивные поиски?

Извините, если вопрос звучит довольно глупо. Я прежде всего из Java фона, и работа с обещаниями / async / await для меня совершенно новая

1 Ответ

0 голосов
/ 07 февраля 2020

Вы не имеете дело с обещаниями правильно. search на самом деле не возвращает «настоящее» обещание, но вызывающая сторона ожидает, что оно это сделает. Поскольку он async, но не возвращает значение напрямую, он фактически возвращает обещание, которое всегда разрешается до undefined. По-видимому, она также предназначена для рекурсивной функции, что затрудняет ее понимание (вы хотели возвратить обещание внутреннего вызова search?).

Как минимум, вы должны начать с поиска вернуть установленную цепочку обещаний:

return db.collection("item")...get().then()

Это позволит вам получить значение, возвращаемое обратным вызовом then.

Я также укажу, что вы начали используйте синтаксис async / await, но никогда не используйте await, чтобы сделать этот код более легким для чтения, что немного сбивает с толку.

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