【发布时间】:2021-05-04 09:31:23
【问题描述】:
我的存储库中有一个函数“getUser”,它根据提供的 id 发出一个代表用户的对象。
fun getUser(id: String) = callbackFlow {
val collectionReference: CollectionReference =
FirebaseFirestore.getInstance().collection(COLLECTION_USERS)
val query: Query = collectionReference.whereEqualTo(ID, id)
query.get().addOnSuccessListener {
val lst = it.toObjects(User::class.java)
if (lst.isEmpty())
offer(null)
else
offer(it.toObjects(User::class.java)[0])
}
awaitClose()
}
我在另一个类中需要这些值。我遍历一个 id 列表,并将收集到的用户添加到一个新列表中。我如何在收集值时等待列表完成,然后再调用 return?
private fun computeAttendeesList(reminder: Reminder): ArrayList<User> {
val attendeesList = arrayListOf<User>()
for (friend in reminder.usersToShare) {
repoScope.launch {
Repository.getUser(friend).collect {
it?.let { user ->
if (!attendeesList.contains(user))
attendeesList.add(user)
}
}
}
}
return attendeesList
}
我不想使用实时数据,因为这不是与 UI 相关的类。
【问题讨论】:
-
请不要发布屏幕截图,它们不可搜索,并且很难建立有用的响应,因为我们需要输入所有内容。请在您的问题中使用代码块粘贴代码。
-
您希望您的
computeAttendeesList在等待时做什么?你想让它暂停吗?还是阻塞当前线程?如果是前者,你应该使用suspend自己的方法,如果是后者,你可以使用runBlocking。无论哪种情况,您都有多种方法可以做到这一点,因此这将有助于获得有关您要在哪个范围内运行以及要阻止哪些线程(如果有的话)的更多信息。 -
对不起@Joffrey,我发布了代码。好吧,我需要是一个阻塞代码,只有在
attendeesList被计算之后,我想被返回以便被另一个函数使用。 -
另外,你的
repoScope是单线程的吗?因为您正在同时更新此处不是线程安全的 ArrayList。 -
如果你想让它提供一个完成的列表,那么有一个
suspend fun getList() : List<T>并从一个挂起的上下文中调用它。我认为您正在尝试用一种解决方案解决两个问题。该流程很好地发出构造列表所需的值,但如果您需要一个完成的列表,感兴趣的对象应该简单地接收这样的东西。
标签: kotlin