в котлин сопрограмм док , это объясняет "разницу между runBlocking и coroutineScope":
Scope builder
В дополнение к области сопрограмм, предоставляемой различными компоновщиками, можно объявить собственную область с помощью компоновщика coroutineScope. Он создает область сопрограммы и не завершается, пока не завершатся все запущенные дочерние элементы. The main difference between runBlocking and coroutineScope is that the latter does not block the current thread while waiting for all children to complete
.
Я не совсем понимаю, код примера показывает
import kotlinx.coroutines.*
fun main() = runBlocking { // this: CoroutineScope
launch {
delay(200L)
println("+++Task from runBlocking")
}
coroutineScope { // Creates a coroutine scope
launch {
delay(500L)
println("+++Task from nested launch")
}
delay(100L)
println("+++ Task from coroutine scope") // This line will be printed before the nested launch
}
println("+++ Coroutine scope is over") // This line is not printed until the nested launch completes
}
журнал:
2019-05-16 10:47:45.107 12239-12239 +++ before enter runBlocking{}
2019-05-16 10:47:45.219 12239-12239 +++ Task from coroutine scope
2019-05-16 10:47:45.320 12239-12239 +++ Task from runBlocking
2019-05-16 10:47:45.620 12239-12239 +++ Task from nested launch
2019-05-16 10:47:45.621 12239-12239 +++ ---after exit runBlocking{}
и +++ Task from nested launch
отображается после +++ Task from runBlocking
, как и ожидалось, так как он имеет задержку 500L.
Но если добавить некоторые другие launch
компоновщики после блока coroutineScop{}
, результат будет сбивающим с толку.
Здесь добавляются два launch
после coroutineScop{}
с задержкой 30L и 100L.
Я ожидал, что журнал для задержки 30L
должен появиться раньше, чем задержка 300L
внутри coroutineScop{}
, но он появляется после того, как все launch
сделаны внутри coroutineScop{}
fun testCoroutines() {
Log.e("+++", "+++ enter testCoroutines_3")
runBlocking {
launch {
println("+++ start Task from runBlocking, with 200L delay")
delay(200L)
println("+++ end Task from runBlocking, with 200L delay")
}
launch {
println("+++ start Task from runBlocking, with 50L delay")
delay(50L)
println("+++ end Task from runBlocking, with 50L delay")
}
launch {
println("+++ start Task from runBlocking, with 70L delay")
delay(70L)
println("+++ end Task from runBlocking, with 70L delay")
}
coroutineScope {
println("+++ enter Task from coroutineScope")
// Creates a coroutine scope
launch {
Log.v("+++", "+++ === start Task from nested launch, 500L")
delay(500L)
Log.v("+++", "+++ --- end Task from nested launch, 500L")
}
delay(100L)
println("+++ in Task from coroutineScope after delay(100L)")
launch {
Log.v("+++", "+++ === start Task from nested launch, 300L")
delay(300L)
Log.v("+++", "+++ --- end Task from nested launch, 300L")
}
println("+++ --- exit Task from coroutine scope") // This line will be printed before the nested launch
}
launch {
println("+++ start Task from runBlocking, with 30L delay")
delay(30L)
println("+++ end Task from runBlocking, with 30L delay")
}
launch {
println("+++ start Task from runBlocking, with 100L delay")
delay(100L)
println("+++ end Task from runBlocking, with 100L delay")
}
}
Log.e("+++", "--- exit testCoroutines_3 scope is over") // This line is not printed until the nested launch completes
}
журнал:
10:35:05.819 4657-4657 +++ enter testCoroutines_3
10:35:05.828 4657-4657 +++ enter Task from coroutineScope
10:35:05.833 4657-4657 +++ start Task from runBlocking, with 200L delay
10:35:05.833 4657-4657 +++ start Task from runBlocking, with 50L delay
10:35:05.833 4657-4657 +++ start Task from runBlocking, with 70L delay
10:35:05.834 4657-4657 +++ === start Task from nested launch, 500L
10:35:05.885 4657-4657 +++ end Task from runBlocking, with 50L delay
10:35:05.905 4657-4657 +++ end Task from runBlocking, with 70L delay
10:35:05.932 4657-4657 +++ in Task from coroutineScope after delay(100L)
10:35:05.933 4657-4657 +++ --- exit Task from coroutine scope
10:35:05.935 4657-4657 +++ === start Task from nested launch, 300L
10:35:06.034 4657-4657 +++ end Task from runBlocking, with 200L delay
10:35:06.235 4657-4657 +++ --- end Task from nested launch, 300L
10:35:06.334 4657-4657 +++ --- end Task from nested launch, 500L
10:35:06.335 4657-4657 +++ start Task from runBlocking, with 30L delay
10:35:06.335 4657-4657 +++ start Task from runBlocking, with 100L delay
10:35:06.366 4657-4657 +++ end Task from runBlocking, with 30L delay
10:35:06.436 4657-4657 +++ end Task from runBlocking, with 100L delay
10:35:06.437 4657-4657--- exit testCoroutines_3 scope is over
думал, что по крайней мере +++ start Task from runBlocking, with 30L delay
должен появиться раньше после +++ === start Task from nested launch, 500L
и до +++ end Task from runBlocking, with 50L delay
, но это не так и появляется после того, как все launch
сделаны в +++ --- end Task from nested launch, 500L
.
Что делает coroutineScope
в блоке сопрограмм?
(я тестировал, используя приложение для Android с нажатием кнопки, чтобы вызвать testCoroutines
)