You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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。

关键修复点:

  1. 确保getBusRoutes是挂起函数:将其定义为suspend fun,这样在协程中调用时会自动等待它执行完成,再继续后续代码。
  2. 移除冗余的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 20:25:53