阵列中的Firebase承诺无法及时解决

时间:2018-02-08 10:20:13

标签: javascript node.js firebase firebase-realtime-database promise

我试图从我的firebase数据库返回3个承诺,一旦所有三个承诺都已完成,我基本上想要渲染一个新页面或做任何事情。所以我做了一个Promise.All(...)但我的名单后来仍然是空的。

我的查询是正确的,因为当我在每个函数中调用console.log()时,我得到了从我的数据库返回的对象但我的Promise.All不等待那些承诺解析而是执行代码内的代码。 Promise.All返回空列表。

app.get('...', function (req, res) {
  //Return first promise from DB save to zone_obj list
  var zone_key = req.params.id;
  var zone_obj = [];
  firebase.database().ref(...).once('value').then((snapme) => {
    zone_obj.push(snapme.val());
  });
  
  //Return second promise from DB save to members list
  var members = [];
  firebase.database().ref(...).on("value", function (snapshott) {
    snapshott.forEach((snapper) => {
      members.push(snapper.val());
    });
  });
  
  //Return third promise from DB save to experiences list
  var experiences = [];
  firebase.database().ref(...).on("value", function (snapshot) {
    snapshot.forEach((snap) => {
      firebase.database().ref(...).once("value").then((snapit) => {
        experiences.push(snapit);
      });
    });
   });
   
  //once all promises have resolved
  Promise.all([experiences,zone_obj,members]).then(values => {
    console.log(values[0]); //returns []
    console.log(values[1]); //returns []
    console.log(values[2]); //returns []
  });
});

1 个答案:

答案 0 :(得分:2)

这实际上不是firebase的问题。 Firebase方法.on("value")实际上是一个绑定到firebase以获取实时更新的侦听器,并且实际上并不是一个promise,并且每次更改该节点上的数据时都会调用您的回调函数。因此,如果您只想分别使用firebase.database().ref(...).set()firebase.database().ref(...).once()方法保存或获取数据。

根据firebase文档

方法

on(eventType, callback, cancelCallbackOrContext, context) returns function()

一旦方法

once(eventType, successCallback, failureCallbackOrContext, context) returns firebase.Promise containing any type

所以将代码更改为以下

app.get('...', function (req, res) {
    var promises = []

    //Return first promise from DB save to zone_obj list
    promises.push(firebase.database().ref(...).once('value'));

    //Return second promise from DB save to members list
    promises.push(firebase.database().ref(...).once('value'));

    //Return third promise from DB save to experiences list
    promises.push(firebase.database().ref(...).once('value'));

    //once all promises have resolved
    Promise.all(promises).then(values => {
        console.log(values[0]); // zone_obj 
        console.log(values[1]); // members 
        console.log(values[2]); // experiences 
    });
});