如何让Kotlin协程函数同步执行?解决API顺序依赖问题
问题:API调用依赖顺序问题
我现在调用2-3个不同API,其中第二个API依赖第一个的返回数据,但编译器会在第一个函数执行完前就调用第二个,导致错误。请问怎么实现第一个函数执行完成后再调用第二个?
/** * Function to get Bus Timings depending on Bus Service No. or Bus Stop Code */ fun determineUserQuery(userInput: String) { // Determine if User Provided a Bus Service No. or Bus Stop Code val userInputResult = determineBusServiceorStop(userInput) viewModelScope.launch { if (userInputResult.busServiceBool) { busServiceBoolUiState = true coroutineScope { // Provided Bus Service, Need get Route first getBusRoutes(targetBusService = userInputResult.busServiceNo) } delay(2000) // Get the Bus Timing for Each Route Log.d("debug2", "String ${_busRouteUiState.value.busRouteArray}") getMultipleBusTimings(busRoutes = _busRouteUiState.value.busRouteArray) } else { // Provided Bus Stop Code coroutineScope { launch { getBusStopNames(targetBusStopCode = userInputResult.busStopCode?.toInt()) } launch { getBusTimings(userInput = userInputResult.busStopCode) } } } } }
解决方案
你的核心问题是误用了delay(2000)这种硬编码等待方式,且嵌套了不必要的coroutineScope,导致无法保证getBusRoutes执行完成后再调用getMultipleBusTimings。
关键修复点:
- 确保
getBusRoutes是挂起函数:将其定义为suspend fun,这样在协程中调用时会自动等待它执行完成,再继续后续代码。 - 移除冗余的
coroutineScope和delay:在viewModelScope.launch的协程体内,挂起函数默认是顺序执行的,直接调用getBusRoutes即可,不需要额外包裹作用域,更不能用固定延迟时间赌请求完成时机。
修复后的代码:
/** * Function to get Bus Timings depending on Bus Service No. or Bus Stop Code */ fun determineUserQuery(userInput: String) { val userInputResult = determineBusServiceorStop(userInput) viewModelScope.launch { if (userInputResult.busServiceBool) { busServiceBoolUiState = true // 调用挂起函数,协程自动等待执行完成 getBusRoutes(targetBusService = userInputResult.busServiceNo) // 此时_busRouteUiState已更新,可安全调用依赖API Log.d("debug2", "String ${_busRouteUiState.value.busRouteArray}") getMultipleBusTimings(busRoutes = _busRouteUiState.value.busRouteArray) } else { // 两个无依赖的API并行调用,这部分逻辑是正确的 coroutineScope { launch { getBusStopNames(targetBusStopCode = userInputResult.busStopCode?.toInt()) } launch { getBusTimings(userInput = userInputResult.busStopCode) } } } } }
补充说明:
- 协程的核心优势就是用顺序代码的写法实现异步等待,只要是挂起函数,在协程中调用时会自动暂停当前协程,直到挂起函数执行完毕再恢复。
- 绝对不要用
delay处理依赖等待,网络请求耗时不确定,硬编码等待时间要么导致等待不足(请求未完成就执行后续代码),要么造成不必要的延迟(请求早已完成却还在等待)。
内容的提问来源于stack exchange,提问作者Michelin_Boi
相关产品推荐
相关产品推荐

