繁体   English   中英

在 kotlin 协程中实现 async-await()

[英]Implementing async- await() in kotlin coroutine

我创建了 function 如下:

fun getPercentage(id:String): String {
    var percentage=""
    scope.launch {
        percentage=repo.getPercentage(id)?.get(0)?.percent.toString()
        Log.e("$$$ value >>","$$$ value >>"+percentage)
    }
    Log.e("$$$ value outside >>","$$$ value >>"+percentage)
    return percenatge
}

在这里,我无法使用变量返回更新值:百分比。

我得到的日志如下:

$$$ value outside >> 
$$$ value >> 50

意味着我不能返回最新的值。 流程出了点问题。

有人建议我使用 async{} 和 await()。 但我不知道这对这里有什么帮助?

请指导。 谢谢。

启动function 在后台启动协程,然后继续。 因此,您的“外部”代码在“内部”协程完成之前运行。

使用异步function 代替从协程返回延迟值:

fun getPercentage(id:String): Deferred<String> {
    return scope.async {
        percentage=repo.getPercentage(id)?.get(0)?.percent.toString()
        Log.e("$$$ value >>","$$$ value >>"+percentage)
    }
}

当然请注意,您更有可能希望将getPercentage设为暂停 function,然后直接调用await

suspend fun getPercentage(id:String): String {
    val percentageDeferred = scope.async {
        percentage=repo.getPercentage(id)?.get(0)?.percent.toString()
        Log.e("$$$ value >>","$$$ value >>"+percentage)
    }
    val percentage = percentageDeferred.await()
    Log.e("$$$ value outside >>","$$$ value >>"+percentage)
    return percentage    
}

您也可能想在await之前做其他事情,否则您最好将repo.getPercentage也设为暂停 function 并直接调用它:

suspend fun getPercentage(id:String): String {
    // if repo.getPercentage is a suspend function, this call suspends
    // like the await in the previous example
    val percentage = repo.getPercentage(id)?.get(0)?.percent.toString()
    Log.e("$$$ value outside >>","$$$ value >>"+percentage)
    return percentage    
}

请参阅 Kotlin 文档中的并发使用异步

我认为在这种情况下您不一定需要使用异步,尤其是。 您只需要知道launch {... }中的任何内容都是异步执行的。 因此,当getPercentage返回时,您的协程可能还没有开始。

牢记这一点,我相信您可能想要更改代码的工作方式。 唯一能让fun getPercentage(id: String): String工作而不改变签名的方法是用scope.launch {... }替换 scope.launch scope.runBlocking {... } ,但你可能不想这样做那是因为它会阻塞你的线程。

相反,您可以将getPercentage更改为suspend方法:

suspend fun getPercentage(id: String): String {
    return repo.getPercentage(id)?.get(0)?.percent.toString()
}

但是, suspend方法只能从协程内部调用。 所以你需要这样称呼它:

scope.launch {
    val percentage = getPercentage("some ID")
    // Now you can use `percentage` for whatever you need.
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM