如何使用异步函数异步监听 Firestore 中的值?

Posted

技术标签:

【中文标题】如何使用异步函数异步监听 Firestore 中的值?【英文标题】:How do I asynchronously listen to a value in Firestore using an async function? 【发布时间】:2019-12-18 09:07:56 【问题描述】:

我在 Flutter 中有一个与 Firestore 通信的异步函数。 有一个服务器功能正在运行,并且我指示任务完成的标志是我使用 StreamSubscription 收听的标志。 StreamSubscription 监听代码用 Future 异步函数包装,但我不明白如何从 StreamSubscription 的函数处理程序返回 Future。

static Future<bool> listenToProcess(
  String doc, Function func) 

  StreamSubscription<DocumentSnapshot> stream =  Firestore.instance.collection('requests').document(doc)
      .snapshots().listen((data)
    if (data.data["done"])
      func(true);
    print ("change " + data.data["done"].toString());
  );

该函数应等待流获得 done=true 未来答案。

【问题讨论】:

【参考方案1】:

您可以在这些情况下使用Completer

static Future<bool> listenToProcess(String doc, Function func) 
  final completer = Completer<bool>();
  final stream = Firestore.instance
      .collection('requests').document(doc).snapshots().listen((data) 
        ...
        completer.complete(data.data["done"]);
      );

  return completer.future;


但是,我发现您可能在这里混淆了一些概念。

    您的函数名称表明它正在处理Stream,但是您返回的是Future。您不应在同一函数中同时使用 StreamFuture 概念。这有点令人困惑。

    您正在传递回调 func,但当您已经返回 Future 时,不应该使用这些回调,因为您可以在 Future 解析时调用 func

我会这样重写这个函数:

static Future<bool> checkIfRequestIsDone(String doc) async 
  // Retrieve only the first snapshot. There's no need to listen to it.
  DocumentSnapshot snapshot = await Firestore.instance
      .collection('requests').document(doc).snapshots().first;

  return snapshot["done"];

和调用者:

bool isRequestDone = await checkIfRequestIsDone(doc);

// Call the server-function as soon as you know if the request is done.
// No need for callback.
serverFunction(isRequestDone); 

【讨论】:

非常感谢您的详尽回答,完成者的工作就像一个魅力。但是 isRequestDone 方法不是很好,因为我需要等到答案为真。如果为 false 代码将继续执行 serverFunction(),不是吗? 然后在调用serverFunction()之前检查isRequestDone是否为真:if (isRequestDone) serverFunction(true);。我真的认为您应该考虑这一点,因为正如我所解释的,您最初的实现混淆了很多概念。 是的,所以我做了什么来省略 func() 代码。我看不出我怎么能简单地使用 if (isRequestDone) 因为我必须以某种方式继续检查它..我肯定不会循环检查,即使没有计时器..我认为流方法是好的,只要我在它变为true后取消它。 Completer 太棒了!非常感谢分享!

以上是关于如何使用异步函数异步监听 Firestore 中的值?的主要内容,如果未能解决你的问题,请参考以下文章

在 dart/flutter 中执行多次从 firestore 获取数据的异步函数

Flutter Firestore 使用异步检索所有文档内容

异步等待 Firestore 用户 ID

从 firebase firestore 参考中获取异步值

Firestore,Flutter,Async:方法不等待异步方法完成

如何在一个类中实现异步