如何在 Dart 中从 Future<String> 返回聊天应用程序的字符串?

How to return a String from a Future<String> in Dart for a chat app?

提问人:jamesglv 提问时间:5/28/2023 更新时间:5/28/2023 访问量:45

问:

在聊天应用程序中,我尝试查询 Firestore 并从“Contacts”集合中以字符串形式返回其他用户的名称。我仍在尝试在 dart 中围绕 async 和 Futures 进行思考,因此当我返回此内容时,它会打印“Instance of Future”而不是 findName 应查询的字符串。

return ListView(
                    children: List.generate(_conversations.length, (i) {
                      

                      DocumentReference? _conversationRef =
                          _conversations[i].reference;
                      Map _conversation = _conversations[i].data() ?? {};



                      String otherUser = _conversation["members"][0] != uid
                          ? _conversation["members"][0]
                          : _conversation["members"][1];



                      Future<String> findName(otherUser) async {
                        var recipName = await FirebaseFirestore.instance
                            .collection("contacts")
                            .where("phone_number", isEqualTo: otherUser)
                            .get().then(

                              (querySnapshot) {
                                 for (var docSnapshot in querySnapshot.docs) {

                                   return docSnapshot.data()['full_name'].toString();
                                 }
                              });


                            if (recipName != null) {
                              return recipName;
                            } else {
                              return otherUser;
                            }
                      }

                      
                      contactName() async {
                        var name = await findName(otherUser);
                        return name.toString();
                      }


                      return ConversationTile(
                          conversationReference: _conversationRef,
                          otherUserId: contactName() ?? "user number");
                    }),
Android iOS Flutter Dart 异步

评论

0赞 jamesdlin 5/28/2023
1. 通过使用 从 a 获取 a。2. 使用代替 .阅读 dart.dev/codelabs/async-awaitTFuture<T>awaitawaitFutuer.then

答:

0赞 CStark 5/28/2023 #1

如果要基于未来构建 UI,则需要使用 FutureBuilder,它可以控制未来结果的状态,并在未来完成后呈现 UI。下面是 FutureBuilder 的简单示例,如果需要,我可以提供更多详细信息。

FutureBuilder(
 future: getMessages(),
 builder:(context, snapshot) {
  if (snapshot.hasData) { // Future Complete 
   return ListView.builder(itemBuilder:(context, index) {
    //build listview 
   },);
  }
 },
 return Center(child: CircularProgressIndicator()); // Future Not Complete / No Data
),
0赞 Vinay 5/28/2023 #2

在 Dart 中,你可以使用 async 和 await 关键字从 Future 返回一个字符串。请点击此链接 https://dart.dev/codelabs/async-await

在您的情况下,更新的代码将是-

return ListView(
  children: List.generate(_conversations.length, (i) {
    DocumentReference? _conversationRef = _conversations[i].reference;
    Map _conversation = _conversations[i].data() ?? {};

    String otherUser = _conversation["members"][0] != uid
        ? _conversation["members"][0]
        : _conversation["members"][1];

    Future<String> findName(String otherUser) async {
      var querySnapshot = await FirebaseFirestore.instance
          .collection("contacts")
          .where("phone_number", isEqualTo: otherUser)
          .get();

      for (var docSnapshot in querySnapshot.docs) {
        return docSnapshot.data()['full_name'].toString();
      }

      return otherUser;
    }

    return FutureBuilder<String>(
      future: findName(otherUser),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return ConversationTile(
            conversationReference: _conversationRef,
            otherUserId: snapshot.data!,
          );
        } else if (snapshot.hasError) {
          return Text("Error: ${snapshot.error}");
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  }),
);

评论

0赞 Imtiaz Ayon 5/28/2023
你不应该在将来的构建器中运行异步函数,因为这样你每次构建小部件时都会运行这个函数。您应该在 initState 或其他地方调用它(不使用 await),并在将来的构建器中使用该变量。api.flutter.dev/flutter/widgets/FutureBuilder-class.html(管理未来)