为何Kotlin runTest中delay挂起协程而yield不挂起?
问题原因解析
- runTest使用的是确定性测试调度器(TestDispatcher),这个调度器不会自动推进时间,也不会主动触发协程切换,所有调度行为都需要显式触发。
yield()在普通协程调度器中是让当前协程主动让权,给同优先级的其他协程执行机会。但在TestDispatcher里,它只会标记当前协程需要暂停,却不会主动唤醒之前挂起的job1——因为这个调度器是“按既定逻辑执行”的,没有收到时间推进或明确的调度指令时,不会主动切换协程。- 换成
delay(1)后,delay会让协程挂起,同时向测试调度器注册一个1毫秒后的唤醒事件。此时调度器会自动把时间推进到事件触发的节点,顺便唤醒之前因delay挂起的job1,两个协程就能交替执行,测试也就通过了。 - 之前用runBlocking能正常工作,是因为runBlocking使用的是普通抢占式调度器,
yield()可以直接触发协程切换,不需要额外的时间推进操作。
内容的提问来源于stack exchange,提问作者Jimbroze
相关产品推荐
相关产品推荐

