【问题标题】:How do I recursively search for results in Firestore?如何在 Firestore 中递归搜索结果?
【发布时间】:2020-02-07 04:19:19
【问题描述】:

我是 Node 和 Firebase 的新手。

我目前正在开发一款游戏的制作计算器,并将游戏物品存储在 Firebase 中。有些项目是复合项目,例如:

1 Lumber Plank = 5 Logs

根据这些要求,我将所有项目构建为一个集合,在 Firebase 中命名为 items

日志将被持久化为:

{
  "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(我假设这来自search函数中的console.log)。

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

不胜感激这里的任何指针/提示。谢谢


根据 Doug 的反馈,

我已经根据你的 cmets 重构了我的代码,并且我看到了一些进展。

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

Log 现在正确输出搜索。

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

但是,如果我理解正确,如果我在这一行中添加它仍然会返回 undefined,对吗?

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

如果是这样,我如何在完成所有递归搜索的同时实际注销整个项目结构?

对不起,如果这个问题听起来有点愚蠢。我主要来自 Java 背景,处理 promises/async/await 对我来说是全新的

【问题讨论】:

    标签: javascript node.js firebase google-cloud-firestore


    【解决方案1】:

    您没有正确处理承诺。 search 实际上并没有返回“真正的”承诺,但调用者希望它这样做。由于它是async,但不直接返回值,它实际上返回的是一个始终解析为undefined 的promise。它显然还打算成为一个递归函数,这使得它更难理解(您是不是要将承诺从内部调用返回到search?)。

    您应该首先让搜索返回它建立的承诺链:

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

    这将让您收到then 回调返回的值。

    我还要指出,您已经开始使用 async/await 语法,但从未承诺使用 await 使这段代码更易于阅读,这有点令人困惑。

    【讨论】:

    • 感谢您的回复,抱歉,我不知道如何使用重构后的代码回复您的帖子,我已经添加了另一篇帖子。
    • 嘿道格,按照你所说的,如果我要编辑我原来的问题,我应该删除原来的帖子并粘贴我的第二个解决方案吗?或在原始帖子下方附加后续问题?抱歉,这是我第一次在 Stackoverflow 上发帖
    猜你喜欢
    • 1970-01-01
    • 2017-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多