How can I launch a coroutine from a suspend function and have it use the current Scope? (so that the Scope doesn't end until the launched coroutine also ends)

我想写下如下内容——

import kotlinx.coroutines.*

fun main() = runBlocking { // this: CoroutineScope
    go()
}

suspend fun go() {
    launch {
        println("go!")
    }
}

但是这有一个语法错误:"未解析的引用:启动".似乎launch必须以下列方式之一运行-

GlobalScope.launch {
    println("Go!")
}

runBlocking {
    launch {
        println("Go!")
    }
}

withContext(Dispatchers.Default) {
    launch {
        println("Go!")
    }
}

coroutineScope {
    launch {
        println("Go!")
    }
}

这些 Select 都不能满足我的需要.要么代码"阻塞"而不是"繁殖",要么它繁殖,但父作用域不会在父作用域本身结束之前等待其完成.

I need it to "spawn" (launch) in the current parent coroutine scope, and that parent scope should wait for the spawned coroutine to finish before it ends itself.

我希望suspend fun中的简单launch是有效的,并使用其父范围.

I'm using Kotlin 1.3 and cotlinx-coroutines-core:1.0.1.

推荐答案

You should make the function go an extension function of CoroutineScope:

fun main() = runBlocking {
    go()
    go()
    go()
    println("End")
}

fun CoroutineScope.go() = launch {
    println("go!")
}

Read this article to understand why it is not a good idea to start in a suspend functions other coroutines without creating a new coroutineScope{}.

约定是:在suspend个函数中,如果需要启动并行协同 routine ,则调用其他suspend个函数并创建新的CoroutineScope个函数.结果是,只有当所有新启动的协同 routine 都已完成( struct 化并发)时,协同 routine 才会返回.

On the other side, if you need to start new coroutines without knowing the scope, You create an extensions function of CoroutineScope, which itself it not suspendable. Now the caller can decide which scope should be used.

Kotlin相关问答推荐

如何使用收件箱文件中的类运行Kotlin应用程序

查看流数据和改进的HTTP请求的模型

使用数据存储首选项Kotlin Jetpack Compose

如何优雅地声明一个StateFlow?

在 Kotlin 中,为什么我们要在闭包中捕获值

Kotlin 接口类型参数

如何在 Spring Boot 3 中为内部类提供运行时提示

返回 kotlin 中的标签和 lambda 表达式

Jetpack Compose:当状态从另一个活动改变时强制重组

Kotlin spring boot @RequestBody 验证未触发

java - 如何将函数作为参数从java传递给kotlin方法?

在 Kotlin 中通过反射获取 Enum 值

在协程中等待侦听器内的数据

`DataBindingUtil` 中的 `bind`、`inflate` 和 `setContentView` 有什么区别

如何在使用 Gradle 的 AppEngine 项目中使用 Kotlin

在java代码中使用kotlin库

在 suspendCoroutine 块中调用挂起函数的适当方法是什么?

这是 Kotlin 中的错误还是我遗漏了什么?

Dagger +Kotlin 不注入

Dagger 2 androidx fragment不兼容类型