使用Anko Coroutines扩展程序的正确方法是什么? [英] What is the correct way of using Anko Coroutines extensions?

查看:177
本文介绍了使用Anko Coroutines扩展程序的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在将一个示例应用程序从RxJava迁移到Kotlin/Anko Corountines,我想知道我是否正在使用它的最佳方法(第一种):

So I am migrating an example app from RxJava to Kotlin/Anko Corountines and I am wondering if I am doing the best (first) approach of it:

fun getPopulationList() {
    val ref = asReference()

    async(UI) {
        try {
            ref().setCurrentState(ViewState.State.LOADING)
            val background = bg {
                repository.populationResponse().execute().body()
            }

            ref().let {
                it.response = background.await()
                it.mvpView?.onGetData(it.response)
                it.setCurrentState(ViewState.State.FINISH)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            ref().mvpView?.onError(e)
        }
    }
}

我正在使用MVP架构,其中我的Presenter基类具有CompositeSubscription,并且在onDestroy的片段或活动方法中,简单地取消预订并清除CompositeSubscription对象.但是我想知道Anko Coroutines的asReference()函数是否也是如此,并且没有必要保存Deferred<T>的列表,然后对其进行迭代并逐个取消.

I am using an MVP architecture where my Presenter base class had a CompositeSubscription and in the onDestroy's fragment or activity method simple unsubscribe and clear the CompositeSubscription object. But i am wondering if the asReference() function from Anko Coroutines does the same and there is no need to save a list of Deferred<T> and then iterate it and cancel one by one.

如果我添加Thread.sleep(5000)来模拟大事务并破坏片段,即使在片段不可见/使用RxJava销毁该片段的情况下,我也能在logcat中看到HTTP响应,所以我想我使用不正确.

BTW if I add a Thread.sleep(5000) to simulate a big transaction and destroy the Fragment I can see in the logcat the HTTP response even after the fragment is not visible/destroyed while with RxJava doesn't happen, so I think I am not using properly.

更新

 fun getPopulationList() {
    val ref = asReference()

    job = launch(UI) {

        try {
            ref().setCurrentState(ViewState.LOADING)
            val background = bg {
                Thread.sleep(5000) //simulate heavy IO

                if (isActive) {
                    repository.populationResponse().execute().body()
                } else {
                    return@bg null
                }
            }

            ref().let {
                it.response = background.await()
                it.mvpView?.onGetData(it.response)
                it.setCurrentState(ViewState.FINISH)
            }
        } catch (e: Exception) {
            RestHttpExceptionHandler().handle(UI, e, ref())
        }
    }
}

我可以在onDestroy()方法中调用job.cancel()时取消协程,但要使其正常工作,我必须检查该作业是否处于活动状态,并转换为if/else并返回或不返回数据.取消工作后,还有什么更好的退货方法吗?

I am able to cancel the coroutine while calling job.cancel() in onDestroy() method but to make it work I have to check if the job is active or not and that translate into an if/else and a return or not data. Is there any better way to return something when the job was cancelled?

推荐答案

您可以在

As you can see in asReference() source it is nothing other than a weak reference and invoke method to get reference that throws CancellationException when object is collected. it does not do anything to cancel operation. just is aware of collected object.

所以您需要保留

so you need to keep reference of a Job or subtype of it to cancel operation.

launch协程生成器返回一个Job实例.这是一个例子:

launch coroutine builder from kotlinx.coroutines returns a Job instance. here is an example:

private lateinit var job: Job

private fun startCoroutines() {
    val ref = asReference()
    job = launch(UI) {
        try {
            val deferred = async(parent = coroutineContext[Job]) {
                    //do some work
                    result//return
            }

            ref().setData(deferred.await())
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

}


override fun onDestroy() {
    super.onDestroy()
    job.cancel()
}

注意:

1-当结果类型不重要时,可以使用launch代替async.

1- when result type is not important launch can be used instead of async.

2-要取消子协程,必须创建父/子作业层次结构.我通过对子协程(async)的parent(launch)Job引用来实现此目的.

2- to do cancellation in child coroutines you must create parent/child job hierarchies. I passed parent(launch) Job reference to child coroutine(async) to achieve this.

3-因为 取消是合作 ,取消实施必须以异步方式完成(请参见示例 3- job.cancel()用于onDestroy取消作业,它是子异步对象.这可以在Presenter中以MVP模式完成.

3- job.cancel() is used in onDestroy cancels job and it's child async. this can be done in Presenter in MVP pattern.

这篇关于使用Anko Coroutines扩展程序的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆