Kotlin coroutine不等待完成

时间:2017-08-23 07:16:28

标签: android kotlin kotlinx.coroutines

我有一个遗留项目,我希望在联系后端时使用协同程序。后端由Hybris提供的sdk处理。例如,它使用齐射,并使用一些回调。我想要的是用协程包装那些回调。但我遇到的问题是协同程序没有等待完成,它启动协同程序,并继续前进到下一行,并且方法返回一个值,并且很久之后协程就完成了。 我的代码:

suspend  fun ServiceHelper.getList(): ListOfWishes {

    return suspendCancellableCoroutine { continuation ->

        getAllLists(object : ResponseReceiver<ListOfWishes> {
            override fun onResponse(response: Response<ListOfWishes>?) {
                continuation.resume(response?.data!!)

            }

            override fun onError(response: Response<ErrorList>?) {
                val throwable = Throwable(Util.getFirstErrorSafe(response?.data))
                continuation.resumeWithException(throwable)
            }
        }, RequestUtils.generateUniqueRequestId(), false, null, object : OnRequestListener {
            override fun beforeRequest() {}
            override fun afterRequestBeforeResponse() {}
            override fun afterRequest(isDataSynced: Boolean) {}
        })
    }
}

辅助方法:

suspend fun ServiceHelper.wishLists(): Deferred<ListOfWishes> {
    return async(CommonPool) {
        getWishList()
    }
}

调用协程的地方:

    fun getUpdatedLists(): ListOfWishes? {
    val context = Injector.getContext()
    val serviceHelper = Util.getContentServiceHelper(context) 
    var list = ListOfWishLists()
    launch(Android) {
        try {
            list = serviceHelper.wishLists().await()
        } catch (ex: Exception){
            Timber.d("Error: $ex")
        }
    }
    return list

因此,不是等待serviceHelper.wishLists().await()完成,而是返回列表。我还尝试使该方法返回runBlocking{},但这只会阻止UI线程,并且不会结束协程。

1 个答案:

答案 0 :(得分:0)

您可以执行以下操作:

class Presenter : CoroutineScope { // implement CoroutineScope to create local scope
    private var job: Job = Job()

    // local coroutine context
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job

    // call this when activity or fragment is destroyed to cancel the job
    fun detachView() {
        job.cancel()
    }

    fun updateLists() = wishLists().then(this) {

        // update your UI here

        // `it` contains the ListOfWishes

    }

    private fun wishLists(): Deferred<ListOfWishes> = async(Dispatchers.IO) {
        getWishList()
    }

    private suspend  fun getWishList(): ListOfWishes = suspendCancellableCoroutine { continuation ->
        getAllLists(object : ResponseReceiver<ListOfWishes> {
            override fun onResponse(response: Response<ListOfWishes>?) {
                continuation.resume(response?.data!!)
            }

            override fun onError(response: Response<ErrorList>?) {
                val throwable = Throwable(Util.getFirstErrorSafe(response?.data))
                continuation.resumeWithException(throwable)
            }
        }, RequestUtils.generateUniqueRequestId(), false, null, object : OnRequestListener {
            override fun beforeRequest() {}
            override fun afterRequestBeforeResponse() {}
            override fun afterRequest(isDataSynced: Boolean) {}
        })
    }
}

扩展功能then

fun <T> Deferred<T>.then(scope: CoroutineScope = GlobalScope, uiFun: (T) -> Unit) {
    scope.launch { uiFun(this@then.await()) }
}

要使用Dispatchers.Main向应用程序的gradle.build文件添加依赖项:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1'

希望它会指出正确的方向。