kotlin 协程 coroutineScope 内包含协程launch 和普通打印。为什么普通打印,先执行而launch后执行
时间: 2023-04-02 11:02:47 浏览: 78
这是因为协程是异步执行的,它会在后台执行,而普通打印是同步执行的,会在当前线程执行。所以在 coroutineScope 内,普通打印会先执行,而协程 launch 会在后台执行,需要等待一定时间才能执行完毕。
相关问题
kotlin 协程作用域中嵌套两个子协程和一个普通的函数,为什么普通函数会先执行
在 Kotlin 协程中,协程是可以嵌套的,而在协程作用域中启动的协程都会遵循作用域的规则。具体来说,当协程作用域被取消时,作用域中启动的所有协程都会被取消。当启动一个新的协程时,它会成为父协程的子协程,如果父协程被取消,那么所有的子协程也会被取消。
在协程作用域中嵌套两个子协程和一个普通函数时,如果普通函数没有被包装在一个协程中启动,那么它将不受协程作用域的影响,它将在当前线程中执行,并且会先于子协程执行。这是因为协程是一种轻量级的线程,它们可以在同一个线程中并发执行,但是它们需要协作才能正确地交替执行。而普通函数不是协程,它不会自动地参与到协程的协作中去。
如果你想让普通函数和子协程同时执行,你可以将普通函数包装成一个协程并在协程作用域中启动它。这样,它就会成为父协程的子协程,遵循协程作用域的规则,同时也能与其他子协程正确地协作执行。例如,可以使用 `launch` 函数启动一个新的协程来包装普通函数:
```kotlin
val scope = CoroutineScope(Dispatchers.Default)
scope.launch {
// 第一个子协程
launch {
println("子协程 1 开始执行")
delay(1000)
println("子协程 1 执行结束")
}
// 第二个子协程
launch {
println("子协程 2 开始执行")
delay(500)
println("子协程 2 执行结束")
}
// 普通函数包装成的协程
launch {
println("普通函数开始执行")
delay(750)
println("普通函数执行结束")
}
}
```
在这个示例中,我们使用 `CoroutineScope` 创建了一个协程作用域,并使用 `launch` 函数分别启动了三个子协程。其中,第一个子协程会执行 1 秒钟,第二个子协程会执行 0.5 秒钟,而第三个子协程是一个包装了普通函数的协程,它会执行 0.75 秒钟。由于这三个子协程都是在同一个协程作用域中启动的,它们将会遵循协程作用域的规则,正确地交替执行。
kotlin协程执行完再执行下一句
在 Kotlin 中,可以使用协程来实现异步操作。如果需要在协程执行完后再执行下一句,可以使用 `runBlocking` 函数或者 `CoroutineScope.launch` 函数的 `join` 方法。
`runBlocking` 函数会阻塞当前线程,直到内部的协程执行完毕。因此,可以将需要等待协程执行完毕后再执行的代码放在 `runBlocking` 函数的后面。
举个例子,假设我们有一个协程函数 `fetchData`,它会异步地从网络中获取数据:
```kotlin
suspend fun fetchData(): String {
delay(3000)
return "Data from network"
}
```
如果我们想要在协程执行完后输出数据,可以这样写:
```kotlin
fun main() = runBlocking<Unit> {
val data = fetchData()
println(data)
}
```
在这个例子中,我们使用 `runBlocking` 函数来阻塞主线程,并在内部启动协程来执行 `fetchData` 函数。当协程执行完毕后,`runBlocking` 函数会返回,我们就可以在后面的代码中使用协程返回的数据了。
另外,如果我们使用 `CoroutineScope.launch` 函数来启动协程,可以在协程对象上调用 `join` 方法来等待协程执行完毕。例如:
```kotlin
fun main() = runBlocking<Unit> {
val job = launch {
val data = fetchData()
println(data)
}
job.join()
println("Coroutine finished")
}
```
在这个例子中,我们使用 `launch` 函数来启动协程,并将返回的 `Job` 对象保存下来。然后,在协程执行完毕后,我们调用 `join` 方法来等待协程执行完毕。最后,我们可以在后面的代码中执行其他操作。