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

用户发起新查询请求时如何取消前序未完成的coroutine协程?

实现方案

核心逻辑是在ViewModel中持有当前查询协程的引用,每次发起新查询前先取消上一次的未完成协程:


步骤1:在ViewModel中新增协程引用变量

声明私有变量存储当前正在执行的天气查询协程的Job实例:

// 放在ViewModel类内部的成员变量位置
private var currentSearchJob: Job? = null

步骤2:修改getWeatherByCityName方法

每次触发查询时,先取消上一次的协程,再启动新协程并保存其Job引用。同时原代码中viewModelScope.launch嵌套launchIn(viewModelScope)属于冗余写法,可以同步优化:

fun getWeatherByCityName(
    cityName: String
) {
    // 先取消上一次未完成的查询协程,已完成的协程调用cancel不会抛出异常
    currentSearchJob?.cancel()
    // 启动新协程并保存Job实例
    currentSearchJob = weatherRepository.getWeatherByCityName(cityName, localeUnit, localeLang)
        .onEach { dataState ->
            when (dataState) {
                is ApiResult.Success -> {
                    prefRepository.setUserInput(cityName)
                    cityId = dataState.data.cityId
                    _screenState.value = dataState
                }
                else -> _screenState.value = dataState
            }
        }
        .launchIn(viewModelScope)
}

注意事项

  • 只要仓库层的网络请求基于Kotlin协程实现(比如使用Retrofit官方协程适配器),协程取消时会自动终止未完成的网络请求,不会产生无效资源消耗
  • 原有UI层的handler.removeCallbacksAndMessages(null)已经实现了输入防抖时延迟任务的取消,搭配协程取消即可完整覆盖所有无效请求的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 08:24:03