Flutter Riverpod StreamProvider在构建小部件之前未等待for循环完成

kiz8lqtg  于 2023-01-02  发布在  Flutter
关注(0)|答案(1)|浏览(132)

我这里有一个StreamProvider:

final secondTabProvider = StreamProvider((ref){
  EmergencyContactsController contacts = EmergencyContactsController(currentUserID: ref.read(authProvider).currentUser!.uid);
  return contacts.getUserEmergencyContacts();
});

我在构建方法中这样调用它:

_secondTab.when(
  data: (data) {
    if (!data.exists){
     return Text("no data")
    }

    Map<String, dynamic doc = data.doc() as Map<String, dynamic>;
    
    List conversations = doc['conversation'];

    // Store the user profiles
    List<EmergencyContactModel> users = [];

    for (Map<String, dynamic> user in userConversations){
                              
      contacts.getContactInfo(
       uid: user['userID']
      ).then((value){
        if (value != null){
         EmergencyContactModel contact = EmergencyContactModel.fromJson(value);

         contact.messageID = value["id"] + ref.read(authProvider).currentUser!.uid;
         users.add(contact);
        }

      });
    }

   return Listview.builder(
    itemCount: users.length,
    itemBuilder: (BuildContext context, int index) => Text(users[index]['name'])
   );
  },
  error: (err, _){
   return Text("Error")
  },
  loading: () => CircularProgressIndicator()

)

getContactInfo()方法是一个异步函数,我需要它在循环继续到下一次迭代之前执行,但它没有这样做。

kwvwclae

kwvwclae1#

我解决了这个问题,我把for循环转换成了它自己的异步函数,如下所示:

// Generate a list of users that the current user has had conversations with
  userinfoGenerator(List userIDs) async {
    // Get the user profiles
    List<EmergencyContactModel> users = [];

    for (Map<String, dynamic> user in userIDs){
     
      Map<String, dynamic>? contactInfo = await contacts.getContactInfo(uid: user['userID']);

      if (contactInfo != null){
        EmergencyContactModel contact = EmergencyContactModel.fromJson(contactInfo);
        contact.messageID =  contactInfo["id"] + ref.read(authProvider).currentUser!.uid;
        users.add(contact);
      }

    }

    return users;
  }

然后我使用Future Builder返回函数的结果,如下所示:

return FutureBuilder(
    future: userinfoGenerator(userConversations),
    builder: (BuildContext context, AsyncSnapshot snapshot){

      // Checking if future is resolved
      if (snapshot.connectionState == ConnectionState.done) {
        // If we got an error
        if (snapshot.hasError) {
          return Center(
            child: CustomText(
              label: '${snapshot.error} occurred',
            ),
          );

          // if we got our data
        } else if (snapshot.hasData) {
          // Extracting data from snapshot object
          final data = snapshot.data;
          return ListView.builder(
              shrinkWrap: true,
              itemCount: data.length,
              itemBuilder: (BuildContext context, int index) {
                List<String> theName = data[index].name
                    .split(" ");
                return Padding(
                  padding: const EdgeInsets.only(
                      top: 12.0),
                  child: CustomListTile(
                      contact: data[index],
                      label: theName.length == 1
                          ? theName[0][0]
                          : "${theName[0][0]} ${theName[theName
                          .length - 1][0]}"
                  ),
                );
              }
          );
        }
      }

      return const Center(
        child: CircularProgressIndicator(
          color: kDefaultBackground,
        ),
      );
    },
  );

相关问题