代码之家  ›  专栏  ›  技术社区  ›  iljau

Kotlin:async的返回映射(start=CoroutineStart.LAZY)

  •  2
  • iljau  · 技术社区  · 7 年前

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

    问题是下面的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")
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   Marko Topolnik    7 年前

    withContext 直到在其中启动的所有协同程序完成后才完成。您可以将您的案例简化为:

    fun main() {
        runBlocking {
            withContext(Dispatchers.Default) {
                launch(start = CoroutineStart.LAZY) { 1 }
            }
            println("not happening")
        }
    }
    

    上下文 不恰当地。你的 getMap() suspend fun .

    你需要什么而不是什么 上下文 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")
    }
    

    在这里,您使用的是全局协同路由作用域,因此不会得到任何自动取消。如果你想解决这个问题,就用别的东西代替它。