【问题标题】:Promises inside nested loops嵌套循环中的承诺
【发布时间】:2019-01-23 08:42:31
【问题描述】:

我有一个对 NoSQL 数据库的查询。由于在这种类型的数据库中,复杂查询的选项并不多,因此我需要在一个循环中对其他表进行两次嵌套查询

由第一个查询创建。使用 Promise,我决定阅读第一个嵌套查询。但是,整个块并没有“等待”最内部的查询,以及它带来的结果

(来自用户)未计算在内。这是简化的代码:

该块执行以下操作:对于每个房间(最外层循环),它读取所有消息(第一个承诺,来自 messageRef),并且对于每条消息,获取用户数据(第二个承诺,来自

用户参考)。第一个嵌套查询没问题(显示所有消息)。但是,并未加载每条消息的用户数据(在这种情况下,为了简单起见,我只是输入了名称)。

messageRef 和 usersRef 对象返回存储在 Promise 数组中的 Promise。最后,当所有都完成时(Promise.all),它返回包含所有数据的数组。

每个“obj”对象都有每个房间的数据。在 obj.messages 中,它包含消息对象数组,并且在每个 obj.messages 中包含用户数据。

roomRef.on('value', function(data){
    var promises = [],
        threads = [],
        counter = 0;
    $.each(data.val(), function(id, obj){
        obj.id = id;
        obj.messages = [];
        var promise = messageRef.child(id).on('child_added', function(data){
            var msgobj = data.val();
            obj.messages.push(msgobj);
            return usersRef.orderByChild('login').equalTo(msgobj.createdBy.login).once('child_added', function(data){
                msgobj.createdBy.name = data.val().name;
            });
        });
        promises.push(promise);
        threads[counter] = obj;
        counter += 1;
    });
    Promise.all(promises).then(function(){
        console.log(threads) // array with all data
    });
});

感谢您的帮助。

【问题讨论】:

    标签: promise nosql


    【解决方案1】:

    如果您需要查询,请使用查询而不是事件回调 child_added。

    child_added 回调不返回承诺。添加数据时触发。更改它们以查询返回的承诺。

    roomRef.on('value', function(data) {
      var promises = [],
      $.each(data.val(), function(id, obj) {
        obj.id = id
        obj.messages = []
    
        var promise = new Promise(resolve => {
          messageRef.child(id).on('child_added', function(data) {
            var msgobj = data.val()
            obj.messages.push(msgobj)
            usersRef
              .orderByChild('login')
              .equalTo(msgobj.createdBy.login)
              .once('child_added', function(data) {
                msgobj.createdBy.name = data.val().name
                resolve(msgobj)
              })
          })
        })
        promises.push(promise)
      })
      Promise.all(promises).then(function(threads) {
        console.log(threads) // array with all data
      })
    })
    

    【讨论】:

    • 你能举个例子吗?谢谢。
    • 那个是firebase数据库吗?为什么你使用 child_added
    • 我编辑了一些例子,请尝试一下。希望对您有所帮助。
    • 我会试试的。很快我给出了反馈。谢谢!
    • Obba,感谢您的帮助,但仍然无法正常工作。仅加载了几个名称。仅当我强制等待时,所有名称都会正确加载: Promise.all(promises).then(function(){ setTimeout(function(){ onComplete(threads); }, 1000); });事实上,这是不正确的(因为查询时间可能会因用户数量而异)。任何想法?谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2016-08-20
    • 2017-06-22
    • 2019-12-25
    • 2015-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多