【问题标题】:Kotlin: return map of async(start = CoroutineStart.LAZY)Kotlin:异步返回映射(start = CoroutineStart.LAZY)
【发布时间】:2018-11-28 14:03:25
【问题描述】:

我想返回延迟启动的协程的映射并在另一个函数中使用它们(启动/取消)。

问题是下面的 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")
    }
}

【问题讨论】:

    标签: kotlin kotlin-coroutines


    【解决方案1】:

    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")
    }
    

    这里您使用的是全局协程范围,因此您不会得到任何自动取消。如果您想解决这个问题,请将其替换为其他内容。

    【讨论】:

      猜你喜欢
      • 2018-01-25
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-16
      • 2021-12-26
      相关资源
      最近更新 更多