【问题标题】:Awaiting for all the callbacks to return before HttpsCallableResult completes在 HttpsCallableResult 完成之前等待所有回调返回
【发布时间】:2019-06-11 14:59:48
【问题描述】:

我在 Unity 中使用 Firebase 函数。主函数在数据库函数完成之前返回。我还是 Node.js 的新手,我仍在努力了解所有 Async Callback 的东西。

我尝试过 CallAsync、ContinueWith 和 Coroutines,但函数总是在第一次返回后继续(我使用 Task.isCompleted() 来检查)。

我的 Node.js 函数是这样的:

exports.my_fn = functions.https.onCall((data, context) => {
    dbsessions.child(id).once("value").then(function(snapshot) {
      if (snapshot.val()) {
        Create();
      } else {
        Move(session);
      }});
  });

function Move(session) {
  if (session["error"]) {
    return return_stuff;
  } else {
      if (some_condition) {
        dbsessions.child(id).set(sson, function(set_error) {
          if (set_error) {
            return return_stuff;
          } else {
            return return_stuff;
          }
      });
      } else {
      dbaimoves.child(stt).child(dif).once("value").then(function(snapshot) {
        if (snapshot.val()) {
          return return_stuff;
        } else {
          if (!first) {
            dbsessions.child(id).set(sson, function(set_error) {
                if (set_error) {
                  return return_stuff;
                } else {
                  return return_stuff;
                }
            });
        } else {
          return return_stuff;
        }
      }
      }, function(errorObject) {
        if (errorObject) {
          return return_stuff;
        }
      });
}}}

var Create = function(data, callback) {
    dbdifficulty.child(data).once("value").then(function(snapshot) {
      if (snapshot.val()) {
        return callback();
      } else {
        dbsessions.child(data.id).set(data, function(set_error) {
          if (set_error) {
            return callback();
          } else {
            return callback();
          }});
    }});
}

(我跳过了不必要的数据以保持问题简单)。基本上就是嵌套返回和数据库操作,回调和函数互相调用。

我的 C# Unity 代码是这样的:

private async Task<string> AddMessageAsync(string text)
    {
        // Create the arguments of the callable function.
        var data = new Dictionary<string, string>();
        data["s"] = text;
        data["d"] = "0";

        var function = func.GetHttpsCallable("my_fn");
        var Tfn = function.CallAsync(data);
        var TRes = await Tfn;

        if (Tfn.IsCompleted)
        {
            JFunc result = JsonUtility.FromJson<JFunc>(TRes.Data.ToString());
            Debug.Log("error:" + result.error);
            return result.move;
        }
        return "error";
    }

上面的代码类似于我的实际代码,它从 Unity 调用该函数,该函数在 Firebase 上运行并很快返回(在它进入 Create() 或 Move() 之前),Unity 接收结果(null)。几秒钟后,该函数在 Firebase 上成功完成,但 Unity 没有收到任何关于此的信息(或者它可能收到,但我无法正确处理它)。

我需要知道:

  1. 如何让主函数返回其他函数返回的内容,以及

  2. 如何让 C# 等待并继续监听返回的值,而不是在第一次返回后认为任务已经完成。如果我只有在结果准备好后才能返回,那就更好了。

【问题讨论】:

  • 我为下面的#1 写了一个答案。请限制自己在每个帖子中回答一个问题,并请阅读how to create a minimal, complete, verifiable example,因为现在您的 JavaScript 代码将无法工作,并且对于不了解您的应用程序的人来说仍然非常复杂。在完全独立的 sn-p 代码中隔离问题是让我们有效帮助您的最佳方式。

标签: node.js firebase unity3d google-cloud-functions


【解决方案1】:

要使 Cloud Functions 代码返回一个值,请确保每个函数都返回一个值或一个承诺。承诺“冒泡”意味着您从最嵌套的代码返回的值将返回到顶层,只要您在每个级别上都有一个 return

因此,在您快速扫描的代码中,您需要:

exports.my_fn = functions.https.onCall((data, context) => {
    return dbsessions.child(id).once("value").then(function(snapshot) {
      if (snapshot.val()) {
        return Create();
      } else {
        return Move(session);
      }});
  });

var Create = function(data, callback) {
    return dbdifficulty.child(data).once("value").then(function(snapshot) {
      if (snapshot.val()) {
        return callback();
      } else {
        return dbsessions.child(data.id).set(data, function(set_error) {
          if (set_error) {
            return callback();
          } else {
            return callback();
          }});
    }});
}

我在这里只检测了顶级my_fnCreate,以显示要做什么。您必须自己为Move 做同样的事情。

【讨论】:

    猜你喜欢
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 2016-05-08
    • 2021-06-20
    • 1970-01-01
    相关资源
    最近更新 更多