【问题标题】:HTTP function return initial array valuesHTTP 函数返回初始数组值
【发布时间】:2018-07-27 02:52:54
【问题描述】:

我已经编写了这个 firebase 云函数,用于计算注册用户数和任意用户数。

// Recalc totals user 
exports.recalcTotalUsers = functions.https.onRequest((req, res) => {
    var arr = {
        anonymous: 0,
        registered: 0
    };

    console.log('starting recalcTotalUsers');
    admin.database().ref("users").once("value").then((snapshot) => {
        snapshot.forEach(function (uid) {
            if (uid.child('/email').val() == ANONYMOUS_STRING) {
                arr.anonymous++;
            } else {
                arr.registered++;
            }
            console.log(`1. ${arr.anonymous}:${arr.registered}`)
        })
    });
    res.status(200).send(`ok registered: ${arr.registered}, anonymous: ${arr.anonymous}`)  
 });

当函数返回时,如果它们具有不同的值,我总是会得到匿名 = 0 和注册 = 0 事件......我做错了什么?

【问题讨论】:

    标签: javascript firebase firebase-realtime-database google-cloud-functions


    【解决方案1】:

    数据库查询是异步的,不会立即完成。您需要使用admin.database().ref("users").once() 的promise return 来等待查询结果,只有在查询成功后才将响应发送给客户端。目前,您的响应会在查询完成之前发送给客户端。

    相反,把对客户端的响应放在从 once() 到 Promise 的回调中,而不是放在外面:

    admin.database().ref("users").once("value").then((snapshot) => {
        snapshot.forEach(function (uid) {
            if (uid.child('/email').val() == ANONYMOUS_STRING) {
                arr.anonymous++;
            } else {
                arr.registered++;
            }
            console.log(`1. ${arr.anonymous}:${arr.registered}`)
        })
        res.status(200).send(`ok registered: ${arr.registered}, anonymous: ${arr.anonymous}`)  
    });
    

    Please read more about Firebase asynchronous APIs.

    【讨论】:

      【解决方案2】:

      你必须改变你的反应!因为此刻,让我们看看你的代码:

      admin.database().ref("users").once("value").then((snapshot) => {
          snapshot.forEach(function (uid) {
              if (uid.child('/email').val() == ANONYMOUS_STRING) {
                  arr.anonymous++;
              } else {
                  arr.registered++;
              }
              console.log(`1. ${arr.anonymous}:${arr.registered}`)
          })
      });
      res.status(200).send(`ok registered: ${arr.registered}, anonymous: ${arr.anonymous}`)
      

      你可能知道,数据库函数都是asynchronous,也就是说它们

      • 执行需要时间
      • 有承诺,因此在执行下一行代码之前不要等待

        res.status(200).send(ok registered: ${arr.registered}, anonymous: ${arr.anonymous})

      在您通过"users" 快​​照查询之前执行该行。 您必须移动它,最佳做法是另一个承诺 (.then(...)),但您可以这样做:

      admin.database().ref("users").once("value").then((snapshot) => {
          snapshot.forEach(function (uid) {
              if (uid.child('/email').val() == ANONYMOUS_STRING) {
                  arr.anonymous++;
              } else {
                  arr.registered++;
              }
              console.log(`1. ${arr.anonymous}:${arr.registered}`)
          })
          res.status(200).send(`ok registered: ${arr.registered}, anonymous: ${arr.anonymous}`)
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-31
        • 1970-01-01
        相关资源
        最近更新 更多