kotlin - 为什么两个收集功能不能在同一个挂起功能中工作?
问题描述
具有两个数据源(本地和远程)的存储库,我请求在初始化时从两个源中获取 accessToken。来自本地和远程的函数都返回一个我试图在初始化中收集的流。但只有第一个收集成功运行,而另一个则没有。这是为什么?有没有一种干净的方式来处理这种用例?
private suspend fun init() {
refreshAccessTokenFromLocal()
refreshAccessTokenFromNetwork()
}
private suspend fun refreshAccessTokenFromNetwork() {
networkDataSource.refreshAccessToken()
.collect { accessToken ->
Timber.d("Debug: refreshing accessToken from network $accessToken")
localDataSource.updateAccessToken(accessToken)
}
}
private suspend fun refreshAccessTokenFromLocal() {
localDataSource.getAccessToken().collect { accessToken ->
Timber.d("Debug: refreshing accessToken from local $accessToken")
accessTokenAsStateFlow.value = accessToken
}
}
解决方案
该collect()
功能不会在后台启动某些东西。它“阻塞”当前协程,直到流程完成。这就是为什么您只看到正在收集的第一个流。
如果您只想从每个流中获取一个值并使用它,您可以调用first()
每个流。但是,这可能不是最佳选择,因为您将按顺序执行操作。
你也可以这样做:
coroutineScope {
val fromNetwork = async { networkDataSource.refreshAccessToken().first() }
val fromLocal = async { localDataSource.getAccessToken().first() }
localDataSource.updateAccessToken(fromNetwork.await())
accessTokenAsStateFlow.value = fromLocal.await()
}
推荐阅读
- html - 窗户半开时如何使卡片不拉伸
- c# - 有没有办法将组合框中的选定项目转换为代码?
- php - 有没有办法在 laravel 的数据库查询生成器中检索数据库表中的单行列
- c++ - 在堆或堆栈上分配的动态创建的字符串 - C
- android-studio - 如何使用另一个 Activity 的 onBackPressed() 方法从 Activity 清除/重置 SharedPreference?
- javascript - 当新图像加载到 beer-reveal 时,Beerslider.js 停止正常工作
- react-native - React 本机 apk 生成失败
- javascript - 基于另一个数组的嵌套过滤器数组
- go - go不支持运算符重载,但是time包怎么解释
- c++ - 如果将鼠标事件设置为透明,您如何仍然使用小部件的功能?