从Firebase中读取完成后返回数组 [英] returning array after finish reading from Firebase

查看:38
本文介绍了从Firebase中读取完成后返回数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将满足一定条件的所有值推送到数组,然后返回此数组.这是我的代码

I want to push all values that satisfy a certain condition to an array then return this array. Here's my code

exports.getNearbyPosts = function (myLat, myLng){
  var query = firebase.database().ref("posts/").orderByKey();
  var listOfItems = [];
  query.once("value")
    .then(function(snapshot) {
      snapshot.forEach(function(childSnapshot) {
        var key = childSnapshot.key;
        var childData = childSnapshot.val();
        var dist = getDistanceBetweenCoord(childData.lat, childData.lng, myLat, myLng);
        if(dist < 10239820938502){
          listOfItems.push(childSnapshot);
        }
    });
  });

  return listOfItems;
}

但是,因为forEach是异步的,并且看来我无法在forEach上使用回调,所以我返回的listOfItems只是一个空数组.我也尝试过".then",但是它只会允许我在".then"内部做更多的事情,并且我想将此数组作为变量返回给代码的其他部分.在执行了forEach之后如何返回正确的数组?

However since forEach is asynchronous, and it seems like I cannot use a callback on forEach, the listOfItems I return would just be an empty array. I have also tried ".then", but it would only allow me to do more stuff inside ".then" and I would like to return this array as a variable to other parts of the code. How can I return the correct array after forEach has been executed?

推荐答案

不是forEach异步(.您可以通过多种方式解决此问题.使用回调,promise或await/async.

It's not the forEach that is async (JavaScript, Node.js: is Array.forEach asynchronous?), it's the query.once("value"). You can solve this problem in a variety of ways. With callbacks, promises, or await/async.

我建议阅读这个非常有启发性的答案,其中涵盖了更多更好的示例:

I suggest reading this very informative answer that covers much more with better examples: How do I return the response from an asynchronous call?

这里的想法是提供一个函数,一旦完成异步工作,但是在forEach中的工作完成之后,就可以使用结果调用该函数.

The idea here is to provide a function that can be called with the result once the asynchronous work is done, but after our work in forEach is complete.

exports.getNearbyPosts = function (myLat, myLng, callback){
  var query = firebase.database().ref("posts/").orderByKey();
  var listOfItems = [];
  query.once("value").then(function(snapshot) {
    snapshot.forEach(function(childSnapshot) {
      var key = childSnapshot.key;
      var childData = childSnapshot.val();
      var dist = getDistanceBetweenCoord(childData.lat, childData.lng, myLat, myLng);
      if(dist < 10239820938502){
        listOfItems.push(childSnapshot);
      }
    });
    callback(listOfItems)
  });
}

getNearbyPosts(0, 0, (result) => {
  console.log(result);
});

承诺是处理异步代码的另一种方法.我建议在此处 https://developer.mozilla.org /en-US/docs/Web/JavaScript/Guide/Using_promises .它将比我能更好地解释它们.

Promises are another way to handle asynchronous code. I suggest reading about them here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises. It will explain them far better than I could.

这是您使用诺言的代码:

Here is your code using promises:

exports.getNearbyPosts = function (myLat, myLng){
  var query = firebase.database().ref("posts/").orderByKey();
  var listOfItems = [];
  return new Promise((resolve, reject) => {
    query.once("value").then(function(snapshot) {
      snapshot.forEach(function(childSnapshot) {
        var key = childSnapshot.key;
        var childData = childSnapshot.val();
        var dist = getDistanceBetweenCoord(childData.lat, childData.lng, myLat, myLng);
        if(dist < 10239820938502){
          listOfItems.push(childSnapshot);
        }
      });
      resolve(listOfItems);
    });
  });
}

getNearbyPosts(0, 0).then(result => {
  console.log(result);
});

这实际上可以进一步简化,因为query.once本身会返回一个承诺.我们可以简单地返回query.once提供给我们的承诺,该承诺将在您的内部函数的.then之后触发一次.我们可以像这样将它们链接在一起.

This can actually be simplified further as it appears query.once returns a promise itself. We can simply return the promise provided to us by query.once which will fire once after the .then of your internal function. We can chain them together like so.

exports.getNearbyPosts = function (myLat, myLng){
  var query = firebase.database().ref("posts/").orderByKey();
  var listOfItems = [];
  
  // We return the promise created by query.once
  return query.once("value").then((snapshot) => {
  
    // our inital .then will do some data filtering
    snapshot.forEach((childSnapshot) => {
      var key = childSnapshot.key;
      var childData = childSnapshot.val();
      var dist = getDistanceBetweenCoord(childData.lat, childData.lng, myLat, myLng);
      if(dist < 10239820938502){
        listOfItems.push(childSnapshot);
      }
    });
    
    // We return here to continue the chain. The next .then that picks this up will have this result
    return listOfItems;
  });
}

// Our last promise resolution in the chain, containing listOfItems
getNearbyPosts(0, 0).then(result => {
  console.log(result);
});

这篇关于从Firebase中读取完成后返回数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆