Open a284628487 opened 3 years ago
coroutineScope 构造块下启动的 coroutine ,失败或者异常 会 影响其它coroutine的执行。
runBlocking {
CoroutineScope(Job()).launch {
supervisorScope {
launch {
delay(1000)
println("I'm launch 1")
throw RuntimeException("what")
}
launch {
delay(1200)
println("I'm launch 2") // 会被执行
}
}
}.join()
CoroutineScope(Job()).launch {
coroutineScope {
launch {
delay(1000)
println("I'm launch 3")
throw RuntimeException("what")
}
launch {
delay(1200)
println("I'm launch 4") // 不会被执行
}
}
}.join()
}
CoroutineScope(Job()).launch
可修改成直接 launch
,区别是前者的执行协程是 "DefaultDispatcher-worker-2 @coroutine#xx" ,而后者是 "main @coroutine#xx"。
runBlocking {
supervisorScope { // or coroutineScope
try {
getInteger(1000)
} catch (e: Exception) {
println("e1: ${e}")
}
val i = getInteger(2000)
println("result1 = $i, ${Thread.currentThread().name}")
}
CoroutineScope(currentCoroutineContext()).launch {
try {
getInteger(1000)
} catch (e: Exception) {
println("e3: ${e}")
}
val i = getInteger(2000)
println("result3 = $i, ${Thread.currentThread().name}")
}.join()
}
可以使用
currentCoroutineContext()
将当前Scope的Dispatcher传给CoroutineScope。上面的示例2中,执行协程的Diaptcher仍然是外部的Scope。
throw exception
e1: java.lang.RuntimeException: what
result1 = 2000, main @coroutine#1
throw exception
e3: java.lang.RuntimeException: what
result3 = 2000, main @coroutine#3
runBlocking {
CoroutineScope(SupervisorJob()).launch {
try {
getInteger(1000)
} catch (e: Exception) {
println("e2: ${e}")
}
val i = getInteger(2000)
println("result2 = $i, ${Thread.currentThread().name}")
}.join()
CoroutineScope(Job()).launch {
try {
getInteger(1000)
} catch (e: Exception) {
println("e4: ${e}")
}
val i = getInteger(2000)
println("result4 = $i, ${Thread.currentThread().name}")
}.join()
}
throw exception
e2: java.lang.RuntimeException: what
result2 = 2000, DefaultDispatcher-worker-1 @coroutine#2
throw exception
e4: java.lang.RuntimeException: what
result4 = 2000, DefaultDispatcher-worker-1 @coroutine#4
Flow
Flow.collect,每次执行 collect 都会触发flow提供者代码。
输出: