数组中的 Firebase Promise 未及时解决

Posted

技术标签:

【中文标题】数组中的 Firebase Promise 未及时解决【英文标题】:Firebase Promises in array not resolving in time 【发布时间】:2018-07-18 21:07:19 【问题描述】:

我正在尝试从我的 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 []
  );
);

【问题讨论】:

回调到on('value', ...是异步的 - 你在任何on('value'可能被“解雇”之前执行promise.all 另外,你在 Promise.all 中的数组是一个数组(由于上述问题是空的)数组,永远不可能是一个 promise 数组 【参考方案1】:

这实际上不是 firebase 的问题。 Firebase 方法.on("value") 实际上是一个监听器,它将绑定到firebase 以获取实时更新,这实际上并不是一个承诺,并且每次该节点上的数据发生更改时都会调用您的回调函数。因此,如果您只想保存或获取数据一次,请分别使用 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 
    );
);

【讨论】:

以上是关于数组中的 Firebase Promise 未及时解决的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 云函数 - 返回未定义、预期的 Promise 或值

Firebase 云函数错误:函数返回未定义、预期的 Promise 或值

函数返回未定义、预期的 Promise 或值 Firebase 日志错误

函数返回未定义,预期Promise或值和通知长时间延迟

(node:11254)UnhandledPromiseRejectionWarning:未处理的promise promise(拒绝id:1):TypeError:无法读取null的属性'l

./~/firebase/app/shared_promise.js 中的错误