本测试通过:
@Test
fun passingTest() {
val emitter = MutableSharedFlow<Int>();
var total = 0;
val handler = emitter.onEach { // <--- onEach bound outside of `launch`
total += it;
println("-> $it : total: $total")
}
GlobalScope.launch {
handler.collect()
}
runBlocking {
for (i in 1..11) {
emitter.emit(1);
}
}
assert(total == 11);
}
但是,如果我将.onEach
移到launch
中,它将不再工作:
x一个一个一个一个x一个一个二个x
发生了什么事?为什么我的onEach
处理程序在连接到启动范围内时丢失了?
1条答案
按热度按时间carvr3hs1#
因此,我自己尝试了这两个测试用例,记录了
GlobalScope.launch
和runBlocking
的块。此测试用例在每次运行时提供随机输出。例如:“12345678910110”即使没有“launch”,有时它也会按预期工作,有时它会在一些值已经发出后开始收集,因此
total
的值小于11。同时,多次运行第二个测试用例并没有让我看到]total]大于0。但是我注意到
GlobalScope
代码在随机时间执行,所以我可以在runBlocking
的输出之前或中间看到launch
的输出,但是onEach
的输出仍然不存在。我决定记录
collect
调用本身注意到它根本没有被调用。因为
GlobalScope.launch
的代码被调用的时间并不重要,我打赌句柄的作用域很重要。onEach
作为一个侦听器工作,因此在runBlocking
中发射有时会在第一个测试用例中更新它。当collect
在正确的时间被调用时,它会收集。但是监听不能在另一个作用域中发生,因此在第二种情况下,您将总是收到一个空流。如果您在第二种情况下添加一个带有emitting something的
GlobalScope.launch
,它将由handler处理并收集。