Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rxLifeScope 及 Async 方法共同使用,调用async方法将导致请求结束回调不被调用 #474

Closed
Jason-Lee-1001 opened this issue Dec 14, 2023 · 1 comment

Comments

@Jason-Lee-1001
Copy link

Jason-Lee-1001 commented Dec 14, 2023

最近项目需要,要将项目的依赖更新一波,其中rxhttp从2.2.x版本更新到2.9.5,其中rxLife中最显著的变化有这几点

为啥被废弃?
1、同一个FragmentActivity/Fragment下,rxLifeScope与lifecycleScope不能共用;同一个ViewModel下,rxLifeScope与viewModelScope不能共用
2、配合RxHttp发请求时,每次都要开启一个协程来捕获异常,这对于再次封装的人,非常不友好; 目前RxHttp的awaitResult操作符一样可以捕获异常,所以rxLifeScope就没了用武之地,是时候退出历史舞台了
3、不能同lifecycleScope或viewModelScope一样,开启协程时,传入CoroutineContext或CoroutineStart参数 亦没有一系列launchXxx方法
4、rxLifeScope配合RxHttp v2.6.6及以上版本发请求时,调用async方法将导致请求结束回调不被调用

其中第4点就影响到原本的项目代码,如下,其中execute是新扩展增加全局业务异常的捕获,其实就是launch方法的二次封装,在2.2.x的版本还正常使用,更新后确实因为几个方法都是用了async的方法,导致没有返回。也将 rxLifeScope 换为 lifecycleScope 试过,问题依旧。

想知道这个具体原因的本质是什么引起的,要继续使用项目当下的这种代码形式又需要做什么改变?望指教

fun refreshContent() {
        rxLifeScope.execute({
            //先读取缓存数据用于展示
            getWarningCardInfo(true)
            getDataModuleList(homeModuleAdapter, true)
            //真实请求获取最新数据
            getWarningCardInfo()
            getDataModuleList(homeModuleAdapter)
            getTarget(sportStatus)
            getArticle()
            homeEditModule.isGone = homeModuleAdapter.collection.isNullOrEmpty()
            delay(2000)
        }, {}, onFinally = { homeRefreshLayout.finishRefresh() })
 }

其中一个方法👇

suspend fun getDataModuleList(adapter: HomeDataModuleAdapter, fetchCache: Boolean = false) = coroutineScope {
    val user = UserConfigMMKV.user ?: return@coroutineScope
    val familyUserId = UserConfigMMKV.selectedFamilyId ?: return@coroutineScope
    val params = hashMapOf<String, Any?>()
    params["fetchHealth"] = true
    params["visible"] = 1
    params["mainUserId"] = user.uid
    params["familyUserId"] = familyUserId
    val list = if (fetchCache) getCacheOnly(Api.Home.HOME_MODULE_LIST, params).toResultArray<CardModule>().tryAwait()
    else getListAsync<CardModule>(Api.Home.HOME_MODULE_LIST, params, enableCache = true).tryAwait()
    adapter.setData(list)
}

getListAsync👇

suspend inline fun <reified T : Any> CoroutineScope.getListAsync(
    method: String,
    params: HashMap<String, Any?>,
    enableEncrypt: Boolean = true,
    enableCache: Boolean = false,
    cacheMode: CacheMode = CacheMode.REQUEST_NETWORK_FAILED_READ_CACHE
): Deferred<MutableList<T>> = getRequest(method, params, enableEncrypt, enableCache, cacheMode).toResultArray<T>().async(this)
fun RxLifeScope.execute(
    block: suspend CoroutineScope.() -> Unit,
    onError: ((Throwable) -> Unit)? = null,
    onStart: (() -> Unit)? = null,
    onFinally: (() -> Unit)? = null
): Job = launch(block, { e ->
    if (e is SessionExpiredException) {
        RxHttpPlugins.cancelAll()
        CommonApp.obtain<CommonApp>().onAuthExpired()
        return@launch
    } else {
        onError.isNotNull({
            it.invoke(e)
        }, {
            if (e.errorMsg.isEmpty()) ToastKit.show("CODE:${e.errorCode}") else ToastKit.show(e.errorMsg)
        })
    }
}, onStart, onFinally)
@liujingxing
Copy link
Owner

麻烦提供个简单的案例,并简单说明下问题吧

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants