如何让第二个协程等待第一个协程准备好所需数据后再执行?
解决方案
方案1:在数据库数据回调中触发API调用
这是最直接的实现方式,当数据库返回成功数据时,直接在回调内执行API调用,天然保证执行顺序,同时遵循生命周期安全:
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { // ... 初始化视图等逻辑 viewLifecycleOwner.lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { myViewModel.someData.collect { data -> when (data) { is DBState.Success -> { // 拿到数据库数据后立即执行API调用 myViewModel.makeCall(data) // 改用协程风格观察API响应,保持代码统一 myViewModel.response.collect { status -> when (status) { is NetStatus.Success -> { // 处理API成功结果 } // 处理API其他状态(加载中、失败) } } } // 处理数据库其他状态(加载中、失败) } } } } }
方案2:用first()获取首个成功数据后执行API调用
如果只需要获取一次数据库数据而非持续监听,可以用first()过滤出成功状态的数据,再执行API调用:
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { // ... 初始化视图等逻辑 viewLifecycleOwner.lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { // 等待并获取第一个成功的数据库数据 val dbData = myViewModel.someData.first { it is DBState.Success } as DBState.Success // 执行API调用 myViewModel.makeCall(dbData) // 观察API响应 myViewModel.response.collect { status -> when (status) { is NetStatus.Success -> { // 处理结果 } // 处理其他状态 } } } } }
方案3:将依赖逻辑移至ViewModel(推荐)
按照MVVM原则,数据依赖逻辑应该内聚在ViewModel中,Fragment仅负责观察最终结果,代码结构更清晰:
ViewModel代码:
class MyViewModel : ViewModel() { private val _someData = MutableStateFlow<DBState>(DBState.Loading) val someData = _someData.asStateFlow() private val _response = MutableStateFlow<NetStatus>(NetStatus.Idle) val response = _response.asStateFlow() // 组合数据库数据获取与API调用的逻辑 fun fetchDataAndCallApi() = viewModelScope.launch { // 等待数据库返回成功数据 val dbSuccessData = someData.first { it is DBState.Success } as DBState.Success // 执行API调用 val apiResult = apiService.makeApiCall(dbSuccessData) // 更新API响应状态 _response.value = if (apiResult.isSuccessful) { NetStatus.Success(apiResult.body()) } else { NetStatus.Error(apiResult.message()) } } }
Fragment代码:
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { // ... 初始化视图等逻辑 viewLifecycleOwner.lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { // 启动ViewModel中的组合逻辑 myViewModel.fetchDataAndCallApi() // 观察API响应结果 myViewModel.response.collect { status -> when (status) { is NetStatus.Success -> { // 处理结果 } // 处理其他状态 } } } } }
内容的提问来源于stack exchange,提问作者asfdasfdsfdfsd
相关产品推荐
相关产品推荐

