我有一个val jobs = arrayListOf<Job>()
//launch and add jobs...
jobs.forEach { it.cancelAndJoin() } // cancels the jobs and waits for completion
个实例的列表,我希望在启动后的某个时刻取消它们。这看起来如下:
cancelAndJoin
不幸的是,这里不可能使用方法参考。原因是:suspend
是jobs.forEach (Job::cancelAndJoin)
函数,正如编译器抱怨的那样:
$#
&#34;错误:(30,24)Kotlin:不支持[可暂停函数的可调用引用]&#34;
为什么这不起作用?
答案 0 :(得分:8)
基本上,支持这一点需要额外的语言设计部分,而不是简单地与协同程序捆绑在一起。
为什么这不重要?因为当您采用普通函数的可调用引用时,例如String::reversed
,你得到类似KFunction1<String, String>
的内容。如果您可以使用suspend
函数执行相同的操作,那么您期望获得什么?
如果它是相同的KFunctionN<...>
,则会出现一个明显的问题,即您可以将其传递到预期普通函数的位置并调用它,这违反了{{1}的规则函数只能在协同程序内部调用(编译器转换其调用站点)。
所以,它应该是更具体的东西。 (我目前只是推测,不知道实际的设计尝试)例如,它可能是suspend
,其SuspendKFunctionN<...>
是暂停功能,或者它可能(不太可能) )是一个特殊的符号,仅用于传递预期invoke(...)
的函数引用,但无论如何,这样的特性需要彻底的设计才能面向未来。
答案 1 :(得分:1)
这些帮助程序目前在Kotlin Standard库中缺少,但是您可以实现自己的帮助。
例如:
suspend fun <T> Iterable<T>.forEachAsync(action: suspend (T) -> Unit): Unit {
val list = this.map { e ->
async(...) {
action(e)
}
}
list.forEach { it.await() }
}
但是,现在传递给异步的上下文取决于您的服务使用的线程模型(即,您要执行多线程还是将所有内容保留在单个线程中)。