【问题标题】:javascript - how to use promises in firebase?javascript - 如何在firebase中使用承诺?
【发布时间】:2018-05-27 11:52:17
【问题描述】:

最近我遇到了一个我不知道如何解决的问题。我问了this 的问题,经过一些努力,我们发现 Firebase 对 Promise 的工作方式与普通请求不同,我无法正确使用它们。
正如the question 中所解释的,我正在用来自 Firebase 的一些信息填充一个数组,当我确定数组已填充时,我需要调用另一个方法,换句话说,当我确定对 Firebase 的调用已经完成时. 这是我现在使用的代码:

var user_pref = firebase.database().ref('/users/'+ self.api.email_id+'/preferenze/');
      var ref = firebase.database().ref('/tag/')
var userTags = [];
var self1 = self;
user_pref.once('value', function(preferenze) { 
  preferenze.forEach(function(t) {
    ref.once('value', function(tags) { 
      tags.forEach(function(t1) {
        if (t.key == t1.key) { 
          console.log("Found " + t1.key)
          userTags.push(t1.key)
        }
        return false;
      });
    })
    return false;
  });
}).then(a =>{
  await this.sleep(1000) //----> WORKAROUND
  console.log("Out")
  this.myTags = userTags
  this.findPoiByTag(this.myTags) //method I have to call when finished
})

我在 sleep 中使用了这种糟糕的解决方法,以确保外部代码在内部代码之后执行。没有它,它会先打印“Out”,然后再打印循环中的所有“Found”。我已经尝试以各种方式将它与 Promise 一起使用,但它仍然不起作用。看看docs here 我找不到任何可以帮助我的东西。

【问题讨论】:

    标签: javascript firebase promise google-cloud-functions


    【解决方案1】:

    这确实很糟糕。

    这应该更接近您的需要:

    var userTags = [];
    var self1 = self;
    user_pref.once('value', function(preferenze) { 
      var promises = [];
      preferenze.forEach(function(t) {
        promises.push(ref.child(t.key).once('value'));
      });
      Promise.all(promises).then(function(snapshots) {
        snapshots.forEach(function(snapshot) {
          if (snapshot.exists()) {
            userTags.push(snapshot.key);
          }
        });
      })
      this.myTags = userTags
      this.findPoiByTag(this.myTags) //method I have to call when finished
    });
    

    这有什么不同:

    1. 它以直观的方式加载每个首选项键(无需加载过多数据的深度嵌套循环)。
    2. 它将所有类别的负载放入一组承诺中。
    3. 它会在所有承诺都解决后调用您的函数。

    【讨论】:

    • 所以 Promise.all(promises) 等中的一段代码与我在代码中执行的相等性检查相同,在 "t.key == t1.key" 中?因为我不明白您在哪里使用称为“ref”的第二个数据库引用。我已经修改了代码,让你更好地理解。我正在使用嵌套循环,因为我必须检查数据库的两个节点之间的质量。
    • 您正在多次加载数据,然后进行客户端比较。这是浪费。我的代码直接查找您要查找的确切密钥,然后使用snapshot.exist() 检查它是否得到结果。在调试器中尝试ref.child(t.key).once('value').then(function(s) { console.log(s.key); }) 看看它是如何工作的。
    • 好的,但我不明白你在哪里进行键之间的比较。我正在数据库的两个不同节点之间进行连接,只有在我比较的键相同时才能获取我需要的数据。我在你的代码中找不到这个。如果我理解的话,你只是在按下你在承诺数组中找到的所有键,然后等待它们。您比较节点中的键的部分在哪里?
    • 据我在您的代码中看到的,您实际上只是在检查数据库中是否存在t.key。这意味着您不需要比较键,所以我的代码可以防止这种情况。
    • ampromises.push(ref.child(t.key).once('value'))中使用ref
    猜你喜欢
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 2018-04-04
    • 1970-01-01
    • 2018-10-06
    相关资源
    最近更新 更多