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

为何添加delay后Kotlin协程未切换仍同步执行?

协程未异步执行的原因及修复方案

问题根源

你当前的代码里,runBlocking循环中每创建一个async协程就立刻调用await(),这会直接阻塞当前协程的执行流程——必须等这个async任务从头到尾跑完,才会继续循环创建下一个协程。相当于把本应异步的任务强制改成了串行执行,自然不会出现delay时的协程切换。

从你的执行日志也能验证这一点:每个链接都是"접근 완료"后立刻完成"파싱 완료",再启动下一个链接的任务,完全是同步顺序执行。

修复方案

要实现真正的并发,需要先批量启动所有async协程,最后统一等待所有任务完成,而不是启动一个等一个。修改后的runBlocking代码如下:

runBlocking {
    // 1. 先批量启动所有协程,将任务存入列表(此时所有协程同时开始执行)
    val jobList = bookLinks.mapIndexed { ranking, bookLink ->
        async { scrapeBookData(browser, bookLink, ranking) }
    }
    // 2. 等待所有协程执行完毕,收集所有结果
    val results = jobList.awaitAll()
    // 3. 过滤非空结果并添加到集合
    bestsellers.addAll(results.filterNotNull())
}

修复后效果

修改后,所有scrapeBookData协程会同时启动:

  • 多个链接会先后打印"접근 완료"(取决于页面加载速度)
  • 所有协程执行到delay(3000)时会挂起,协程调度器会切换到其他未挂起的协程继续执行
  • 3秒后,所有挂起的协程会恢复执行,陆续打印"파싱 완료"

额外注意事项

如果你的Browser实例不是线程安全的,可能需要给async指定合适的调度器(比如async(Dispatchers.IO)),避免并发操作带来的线程安全问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 06:43:14