我想返回懒惰启动的协程的地图,并在另一个函数中使用它们(启动/取消)。
问题是以下挂起的getMap()函数。为什么会这样,并且有可能从函数中返回此类映射?
import kotlinx.coroutines.*
suspend fun getMap(): LinkedHashMap<String, Deferred<Any>> {
return withContext(Dispatchers.Default) {
val map = linkedMapOf<String, Deferred<Any>>()
map["1"] = async(start = CoroutineStart.LAZY) { 1 }
map["2"] = async(start = CoroutineStart.LAZY) { 2 }
map;
}
}
fun main() {
runBlocking {
val map = getMap()
println("not happening")
}
}
答案 0 :(得分:3)
withContext
直到完成其中所有启动的协同程序才能完成。您可以将情况简化为:
fun main() {
runBlocking {
withContext(Dispatchers.Default) {
launch(start = CoroutineStart.LAZY) { 1 }
}
println("not happening")
}
}
它也没有完成。之所以会这样做,是因为您不恰当地使用了withContext
。您的getMap()
没有理由成为suspend fun
。
您需要为withContext
的这些调用设置协程范围,而不是async
。例如,这将起作用:
fun getMap(): Map<String, Deferred<Any>> =
linkedMapOf<String, Deferred<Any>>().also { map ->
with(GlobalScope) {
map["1"] = async(start = CoroutineStart.LAZY) { 1 }
map["2"] = async(start = CoroutineStart.LAZY) { 2 }
}
}
fun main() {
val map = getMap()
println("now it's happening")
}
在这里,您正在使用全局协程范围,因此不会得到任何自动取消。如果您要解决此问题,请换成其他东西。