无法使用promise在阵列中“捕获”Firebase快照

时间:2017-08-21 17:38:59

标签: javascript firebase firebase-realtime-database promise

我知道使用Javascript promises加载返回的Firebase对象有很多问题和答案,但我没有成功捕获数组中的数据。

问题:我已设置一个数组(下面为Run Functional Tests)以迭代方式接收Firebase快照的值,但退出{{1}后数组仍为空}循环。

database.js:

productArray

问题:我认为我使用的是forEach错误,但无法弄清楚如何(也是新的异步函数)。感谢您提供有关如何成功加载 getProductList = function(){ let productArray =[]; loadFBData = function(){ firebase.initializeApp(config); return firebase.database().ref().once("value", function(snapshot){ return snapshot.val(); }); } Promise.all([loadFBData()]).then(function(snapshot) { snapshot.forEach(function(product) { productArray.push(product.val()); }); }); } 的任何提示。

修改:详细说明,似乎Promise.all正在加载正确的Firebase数据,productArray正在循环遍历snapshot中的每个项目,但forEachsnapshot语句之外变为(或保持)为空。

更新我实现了以下所有建议,但程序将不会停止足够长时间从快照对象构建数组。去年我使用了Angularfire的productArray函数,该函数在让程序等待方面非常有效,所以我不明白为什么普通的JS Promise.all在这里不起作用。诉诸$loaded是否有意义?我甚至试图结合alexmac和Pointy的建议,但没有雪茄:

promise

2 个答案:

答案 0 :(得分:1)

背景

我认为你错过了对promises和Firebase SDK的理解。

首先,请注意所有Firebase SDK函数都会返回promise,因此无需创建自己的函数。其次,Promise.all是为了结合多个承诺。单个承诺可以通过简单的.then()链接起来。

我在这里有一个关于保存和查询数据的视频:Save and Query Firebase Data

我还有另一个关于承诺的视频:Promises

加载Firebase

您应该在页面的顶部初始化firebase。它只需要初始化一次,所以不要在函数内初始化它。

您可以在页面上加载Firebase SDK后立即致电firebase.initializeApp(config)。或者您可以参考Firebase Hosting的init.js,如下所示。

实施例

以下示例加载Firebase SDK,使用我的测试db的init.js文件来初始化firebase,然后查询,操作并返回一个数组。

请注意,Firebase不支持零索引数组,因此从Firebase返回的所有内容都将是未分类的对象。此示例显示了几种不同的返回数据的方法:)

<html>
  <head>
    <script src="https://www.gstatic.com/firebasejs/4.3.0/firebase.js"></script>
    <script src="https://quiver-two.firebaseapp.com/__/firebase/init.js"></script>    
    <script>
      function loadFirebaseArray(path) {
        return firebase.database().ref(path).once('value').then(snap => snap.val());
      }

      function toArray(items) {
        return Object.keys(items).reduce((array, key) => {
          const value = items[key];
          array.push({key, value});
          return array;
        }, []).sort();
      }

      loadFirebaseArray('stackoverflow').then(items => {
        console.log('items', items);

        const asArray = toArray(items);
        alert(JSON.stringify(asArray));

        const justTheValues = asArray.map(x => x.value).sort();
        alert(justTheValues);
      });
    </script>
  </head>

</html>

答案 1 :(得分:0)

一个工作示例可能如下所示:

getProductList = () => {
  let loadFBData = () => {
    firebase.initializeApp(config);
    return new Promise(resolve => {
      firebase.database().ref().once('value', resolve);
    });
  }

  let productArray =[];
  loadFBData()
    .then(snapshot => {
      productArray = Object.keys(snapshot).map((key, prod) => prod);
}

在这里,我使用 promisification firebase查询创建承诺。所以loadFBData返回一个promise,我可以创建一个promise链或使用ES7 async / await等到promise将被用来使用result。