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

如何在Kotlin协程中等待请求完成并返回结果?

正确实现协程等待API请求并返回结果的方案

错误实现分析

你之前的两种写法问题出在:

  1. 第一种实现:普通函数里启动协程后直接返回初始值,协程在后台异步执行,函数返回时API请求还没完成,所以拿到的永远是默认的"unknown",后续协程修改变量的操作对已返回的结果没有影响。
  2. 第二种实现:job变量定义在runBlocking内部,外部根本无法访问;同时用Dispatchers.Main执行API请求(网络请求必须放在IO线程),再加上主线程被runBlocking阻塞后,协程需要主线程资源却无法获取,直接导致死锁停滞。

推荐实现方案

方案1:使用挂起函数(规范做法,适配协程上下文)

把函数改成suspend类型,让它在协程环境中被调用,完全避免线程阻塞:

suspend fun getClient(): String? {
    // 强制在IO线程执行API请求(如果你的callsApi.getClient本身是挂起函数且已处理线程切换,可省略withContext)
    val response = withContext(Dispatchers.IO) {
        callsApi.getClient(GetClientDTO(phonenumberString))
    }
    val body = response.body()
    // 省略body解析为nameObject的逻辑...
    return body?.let { nameObject.getString("fullName") } ?: "unknown"
}

调用示例(必须在协程作用域内,比如ViewModel的viewModelScope或Activity的lifecycleScope):

// 在ViewModel中调用
viewModelScope.launch {
    val nameClient = getClient()
    // 拿到结果后处理UI或业务逻辑
}

方案2:同步阻塞获取结果(仅适用于非UI线程场景,不推荐)

如果必须在非协程环境同步拿到结果,用runBlocking指定IO线程,避免阻塞主线程:

fun getClientBlocking(): String? {
    return runBlocking(Dispatchers.IO) {
        val response = callsApi.getClient(GetClientDTO(phonenumberString))
        val body = response.body()
        // 省略解析逻辑...
        body?.let { nameObject.getString("fullName") } ?: "unknown"
    }
}

注意:此方法会阻塞调用线程,绝对不能在主线程使用,否则会造成UI卡顿甚至ANR。


内容的提问来源于stack exchange,提问作者herz88888888

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:15:10