Kotlin:return 异步映射(start = CoroutineStart.LAZY)
Kotlin: return map of async(start = CoroutineStart.LAZY)
我想 return 映射延迟启动的协程并在另一个函数中使用它们 (start/cancel)。
问题是下面的 getMap() 函数挂起。为什么会这样,是否可以从函数 return 这样的映射?
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")
}
}
withContext
在其中启动的所有协程完成之前不会完成。您可以将您的案例简化为:
fun main() {
runBlocking {
withContext(Dispatchers.Default) {
launch(start = CoroutineStart.LAZY) { 1 }
}
println("not happening")
}
}
也没有完成。你陷入困境的原因是你不恰当地使用了withContext
。你的 getMap()
没有理由成为 suspend fun
。
您需要的是为这些 async
调用设置协程范围,而不是 withContext
。例如,这将起作用:
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")
}
此处您使用的是全局协程范围,因此不会自动取消。如果你想解决这个问题,用别的东西代替它。
我想 return 映射延迟启动的协程并在另一个函数中使用它们 (start/cancel)。
问题是下面的 getMap() 函数挂起。为什么会这样,是否可以从函数 return 这样的映射?
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")
}
}
withContext
在其中启动的所有协程完成之前不会完成。您可以将您的案例简化为:
fun main() {
runBlocking {
withContext(Dispatchers.Default) {
launch(start = CoroutineStart.LAZY) { 1 }
}
println("not happening")
}
}
也没有完成。你陷入困境的原因是你不恰当地使用了withContext
。你的 getMap()
没有理由成为 suspend fun
。
您需要的是为这些 async
调用设置协程范围,而不是 withContext
。例如,这将起作用:
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")
}
此处您使用的是全局协程范围,因此不会自动取消。如果你想解决这个问题,用别的东西代替它。