android - 如何在不等待结果的情况下在另一个内部运行挂起功能?

标签 android kotlin kotlin-coroutines coroutine coroutinescope

我有一个场景,我的代码必须发送一个 api 调用并继续其工作(其中包含另一个 api 调用),而无需等待第一次调用的结果。
现在我在我的 View 模型中这样做

fun showItem(id:Int) {
   launch{
       repo.markItemRead(id)
   }
   launch {
       try {
           val item = repo.getItemById(id).getOrThrow
           commands.postValue(ShowItemCommand(item))
       } catch (t:Throwable) {
           commands.postValue(ShowError(R.string.error_retrieve_item))
           repo.logError(t)
       }
   }
}
这调用了具有这两个功能的存储库
suspend fun markItemRead(id) {
    try {
        service.markItemAsRead(id)
    } catch(ignored:Throwable) {
    }
}

suspend fun getItemById(id) : Result<ItemData> {
    return try {
       val response : ItemEntity = service.getItemById(id)
       val item  = response.toData()
       Result.Success(item)
    } catch (t:Throwable) {
        Result.Failure(t)
    }
}
如果存储库完成所有这些工作,我会更喜欢它,因为每次都必须遵循另一个。
不幸的是,当我尝试在我的存储库中做这样的事情时:
suspend fun getItemById(id:Int) : Result<ItemData> {
    try {
        service.markItemAsRead(id)
    } catch(ignored:Throwable) {
    }
    return try {
       val response : ItemEntity = service.getItemById(id)
       val item  = response.toData()
       Result.Success(item)
    } catch (t:Throwable) {
        Result.Failure(t)
    }
}
它等待 markItemAsRead在继续之前完成的功能
除了定义存储库的范围并将 markItemAsReadlaunch 内调用(我已经读过在挂起函数中执行此操作是不正确的)在存储库中是否有另一种方法?

最佳答案

您可以使用 coroutineScope supervisorScope 在存储库中,具体取决于您的需要。这两个函数都是为并行分解工作而设计的。一旦给定 block 及其所有子协程完成,这些函数就会返回。
coroutineScope 中的任何子协程失败,这个范围失败,所有其余的 child 都被取消。不像 coroutineScopesupervisorScope 中的子协程失败不会导致此范围失败并且不会影响其其他子级,因此可以实现用于处理其子级故障的自定义策略。
请选择最适合您的需求。使用示例:

suspend fun getItemByIdAndMarkRead(id: Int) : Result<ItemData> = supervisorScope {
    launch {
        try {
            service.markItemAsRead(id)
        } catch(ignored:Throwable) { }
    }

    return@supervisorScope withContext(Dispatchers.Default) {
        try {
            val response : ItemEntity = service.getItemById(id)
            val item  = response.toData()
            Result.Success(item)
        } catch (t: Throwable) {
            Result.Failure(t)
        }
    }
}
service.markItemAsRead(id)service.getItemById(id)将并行执行。

关于android - 如何在不等待结果的情况下在另一个内部运行挂起功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63696605/

相关文章:

android - 设备上的 Eclipse Android 运行应用程序。什么都没发生

android - Android中ClipData中的 "label"参数到底是什么?

java - JDBC 显示语法错误,但查询在 HeidiSQL 中运行正常

kotlin - Kotlin 中 var 和 val 有什么区别?

Java 8 日期 API - 获取月份中的一周抛出 UnsupportedTemporalTypeException : Unsupported field: DayOfWeek

kotlin - 何时使用 Kotlin suspend 关键字?

kotlin - InternalCoroutinesApi注解是什么意思

android - 背景图像拉伸(stretch)

android - Android 手机上的 ROS

android - 使用协程更新 UI 异步调用