简体   繁体   English

如何将数组从一个函数传递到另一个函数作为Cloud Function中的引用

[英]How to pass an array from one function to another as reference in Cloud Function

I have one function getUsers where I have one array jsonResponse . 我有一个功能getUsers我有一个数组jsonResponse I am passing that array to computeData function. 我正在将该数组传递给computeData函数。 I want computeData function should be able to add items in jsonResponse array itself. 我希望computeData函数应该能够在jsonResponse数组本身中添加项目。

But below code is not adding in same array, as it always return empty array in response.send function. 但是下面的代码没有添加相同的数组,因为它总是在response.send函数中返回空数组。

index.js index.js

exports.getUsers = functions.https.onRequest((request, response) => {
  var x = [];

  var xLocation,
    yLocation = [],
    jsonResponse = [];

  // print algorithm name
  console.log(request.query.algo);

  let geoFire = new GeoFire(db.ref("/users/" + request.query.userId));

  geoFire.get("location").then(function(location) {
    xLocation = location;
  });

  db
    .ref("/users/" + request.query.userId)
    .once("value")
    .then(function(snapshot) {
      var jsonObject = snapshot.val();
      var basicProfileJsonObject = jsonObject.basicProfile;
      for (var key in basicProfileJsonObject) {
        if (utils.isNumber(basicProfileJsonObject[key])) {
          x.push(basicProfileJsonObject[key]);
        }
      }
      db.ref("/users/").once("value").then(function(snapshot) {
        var y = [];
        snapshot.forEach(function(item) {
          var user = item.val();
          let userId = user.basicProfile.userId;
          if (userId !== request.query.userId) {
            if (xLocation == null) {
              computeData(x, user, request.query.algo, jsonResponse);
            } else {
              let geoFire = new GeoFire(db.ref("/users/" + userId));
              geoFire.get("location").then(function(location) {
                if (location === null) {
                  console.log(
                    "Provided key is not in GeoFire, will ignore profile"
                  );
                  computeData(x, user, request.query.algo, jsonResponse);
                } else {
                  console.log("Provided key has a location of " + location);
                  var distance = GeoFire.distance(xLocation, location); // in km
                  console.log("Distance: " + distance);

                  if (distance < 15) {
                    computeData(x, user, request.query.algo, jsonResponse);
                  }
                }
              });
            }
          }
        });
        response.send(jsonResponse);
      });
    });
});

function computeData(x, user, algo, jsonResponse) {
  var similarityCount,
    y = [];

  var basicProfileJsonObject = user.basicProfile;
  for (var key in basicProfileJsonObject) {
    if (utils.isNumber(basicProfileJsonObject[key])) {
      y.push(basicProfileJsonObject[key]);
    }
  }

  if (algo === "cosine") {
    // compute cosine value
    similarityCount = cosineUtils.cosineSimilarity(x, y);
  } else if (algo == "euclidean") {
    // compute euclidean distance value
    similarityCount = 1 / (1 + euclidean(x, y));
  } else if (algo === "pearson-correlation") {
    // compute pearson correlation coefficents
    similarityCount = pcorr.pearsonCorrelation(x, y);
  }
  console.log(x);
  console.log(y);
  console.log(similarityCount);
  jsonResponse.push(user);
}

Does anyone know how to pass array as reference and add items into it in Cloud Function for Firebase ? 有谁知道如何传递数组作为参考,并在Cloud Function for Firebase中向其中添加项目?

Your else statement is a promise which means your loop would have finished and called response.send(jsonResponse); else语句是一个promise ,这意味着你的循环就已经完成,并呼吁response.send(jsonResponse); by the time it gets to computeData() in your else statement. computeData()您的else语句中到达computeData()时。

Try something like this, it doesn't touch all your variables but the main idea is to use Promise.all with computed values as resolved - 试试这样的方法,它不会涉及到所有变量,但主要思想是使用Promise.all并使用Promise.all resolved计算值-

exports.getUsers = functions.https.onRequest((request, response) => {
  // blah blah
  var y = []; // store promises that resolves your computed value
  snapshot.forEach(function(item) {
    // blah blah
    if (xLocation == null) {
      y.push(Promise.resolve(computeData());
    } else {
      y.push(computeAnotherData(userId));
    }
  });

  Promise.all(y)
    .then(values => {
      response.send(values);
    });
});

function computeAnotherData(userId) {
  let geoFire = new GeoFire(db.ref("/users/" + userId));
  return geoFire.get("location").then(function(location) {
    return computeData();
  });
}

Hope it makes sense. 希望有道理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM