【问题标题】:Create Future based on result of another Future根据另一个 Future 的结果创建 Future
【发布时间】:2019-07-01 00:47:17
【问题描述】:

我有一个远程异步 firebase 函数“checkSubscription”,如果用户有有效订阅,则返回“true”或 或“N”,其中 N 表示用户用完之前剩余的积分数。

为了跟踪完成情况,我的班级中有这两个未来:

Future<bool> hasSubscription;
Future<int> remaining;

假设这些数据类型不能更改。 远程函数是这样调用的:

CloudFunctions.instance
        .call(functionName: 'checkSubscription');

这个函数返回一个Future&lt;dynamic&gt; 和结果。

我正在为将我的两个字段分配所需类型所需的 Future 逻辑而苦苦挣扎。 这是我想出的

Future<void> checkIfUserHasSubscription() async {
    await Future < dynamic > remainingS = CloudFunctions.instance
        .call(functionName: 'isValid');

    if (remaining == "true")
      hasSubscription = true;
    else {
      hasSubscription = false;
      remaining = int.parse(remaining);
    }
  }

显然这不起作用,因为我分配的是 bool 而不是 Future

有什么建议吗?

【问题讨论】:

  • 你为什么不只使用bool 来代替?
  • 因为我的代码中有很多地方在等待结果。如果数据类型是 Future 我可以简单地:在每个地方等待 hasSubscription,而不是在结果进来后仔细创建回调来更新每个地方。
  • 好吧。我只是要求了解您是否不能以错误的方式使用它。要与Future 一起使用,请参阅答案。

标签: asynchronous dart async-await flutter


【解决方案1】:

据我了解,您希望拥有两个稍后完成的期货。当你调用 check 函数时,这些期货应该立即可用,但只有在你有结果时才能完成。

为此,您应该使用Completer

我假设您只调用一次检查函数。如果不是,那么您应该在每次调用时在函数内部创建一个新的完成程序,并将期货存储在可变字段中。

Future<bool> _hasSubscription;
Future<int> _remaining;
Future<boo> get hasSubscription => 
  _hasSubscription ?? throw StateError("Call checkIfUserHasSubscription first");  
Future<int> get remaining => 
  _remaining ?? throw StateError("Call checkIfUserHasSubscription first");
Future<void> checkIfUserHasSubscription() async {
  // Maybe: if (hasSubscription != null) return;
  var hasSubscriptionCompleter = Completer<bool>();
  var remainingCompleter = Completer<int>();
  _hasSubscription = hasSubscriptionCompleter.future;
  _remaining = remainingCompleter.future;
  var remainings = await
      CloudFunctions.instance.call(functionName: 'isValid');
  if (remaining == "true") {
    hasSubscriptionCompleter.complete(true);
    remainingCompleter.complete(0); // or never complete it.
  } else {
    hasSubscriptionCompleter.complete(false);
    remainingCompleter.complete(int.parse(remaining));
  }
}

【讨论】:

    【解决方案2】:

    您可以将结果分配给Future

    hasSubscription = Future&lt;bool&gt;.value(true);

    【讨论】:

    • 这不是只有在异步调用完成后才会执行吗?这个想法是同步获取 Future 而不是在 CloudFunctions.instance .call 已经完成之后(因为那样我可以拥有“完整”布尔值)。
    • 这将在此时设置bool,并且该变量等待值的所有调用都将实际触发。
    猜你喜欢
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多