如何在for循环中执行嵌套数据库查询?

时间:2017-11-15 01:16:06

标签: javascript node.js firebase firebase-realtime-database google-cloud-functions

supportChat: function(){
    return functions.https.onRequest((req, res) => {
        var userId = req.query.userId;
        var object = {};
        db.ref("/users/-KwZ2N38Q6a1a87p982/threads").orderByKey().once('value').then(function(snapshot) {
            var snap = snapshot.val();
            var keys = Object.keys(snap);

            for (var i = 0; i < keys.length; i++){
                k = keys[i];
                db.ref("/threads/"+k+"/lastMessage").orderByKey().once('value').then(function(snapshot){
                    var snapshot = snapshot.val();
                    if (snapshot[i]["sender"] != "-KwZ2N38Q6a1a87p982"){
                       object[snap[i]["messageID"]] = snapshot;
                    }
                });
            }
            console.log(object);
            return res.status(200).send(object);
        });
    });
},

我的数据库中的每个用户都有一个线程子,它显示了他们所有的聊天线程。然后我们有另一个数据库的线程部分,它包含该线程的所有数据。

我要做的是检查特定用户的线程ID对数据库的线程部分,以找到线程中最后一条消息未被我(当前用户)发送的所有线程。

我不知道为什么我在努力解决这个问题。将一个满足我条件的每个线程的所有snapshot.val()一次性发送到端点的正确方法是什么?也许我的方法很遥远。

1 个答案:

答案 0 :(得分:1)

要知道for循环中的所有承诺何时完成,您可以累积从循环中获得的承诺数组,然后使用Promise.all()知道它们何时完成。

您还需要保护for循环索引,以便for循环的每次调用都维护自己的索引,以便在调用异步.then()处理程序时仍然正确。您可以通过将for循环切换为使用let i代替var i来实现此目的。

supportChat: function(){
    return functions.https.onRequest((req, res) => {
        let userId = req.query.userId;
        let  object = {};
        db.ref("/users/-KwZ2N38Q6a1a87p982/threads").orderByKey().once('value').then(function(snapshot) {
            let snap = snapshot.val();
            let keys = Object.keys(snap);
            let promises = [];

            for (let i = 0; i < keys.length; i++){
                let k = keys[i];
                promises.push(db.ref("/threads/"+k+"/lastMessage").orderByKey().once('value').then(function(snapshot){
                    let snapshot = snapshot.val();
                    if (snapshot[i]["sender"] != "-KwZ2N38Q6a1a87p982"){
                       object[snap[i]["messageID"]] = snapshot;
                    }
                }));
            }
            return Promise.all(promises).then(() => {
                console.log(object);
                return res.send(object);
            });
        }).catch(err => {
            console.log(err);
            return res.sendStatus(500);
        });
    });
},

关于代码的其他评论:

仅供参考,如果您尝试从supportChat()函数中实际返回某些内容,请指明它是什么。现在,您不希望从该函数调用返回什么。

并且,您不需要.status(200)部分内容:

res.status(200).send(object);

你可以这样做:

res.send(object);

所有这些都将自动使用200的状态。

并且,您需要一个.catch()处理程序来捕获错误并在错误情况下发送响应。