【发布时间】:2018-09-20 13:49:48
【问题描述】:
给定一个返回模型的 API(由 Retrofit 实现)。我使用扩展函数将老式的Call 包装成Deferred:
fun <T> Call<T>.toDeferred(): Deferred<T> {
val deferred = CompletableDeferred<T>()
// cancel request as well
deferred.invokeOnCompletion {
if (deferred.isCancelled) {
cancel()
}
}
enqueue(object : Callback<T> {
override fun onFailure(call: Call<T>?, t: Throwable) {
deferred.completeExceptionally(t)
}
override fun onResponse(call: Call<T>?, response: Response<T>) {
if (response.isSuccessful) {
deferred.complete(response.body()!!)
} else {
deferred.completeExceptionally(HttpException(response))
}
}
})
return deferred
}
现在我可以像这样得到我的模型:
data class Dummy(val name: String, val age: Int)
fun getDummy(): Deferred<Dummy> = api.getDummy().toDeferred()
但是我如何修改Deferred 中的对象并返回Deferred:
fun getDummyAge(): Deferred<Int> {
// return getDummy().age
}
我是协程的新手,所以这可能不是这里的工作方式。假设我是RxJava 的粉丝,我会像这样实现这种情况:
fun getDummy(): Single<Dummy> = api.getDummy().toSingle()
fun getDummyAge(): Single<Int> = getDummy().map { it.age }
那么我应该尝试从getDummyAge 函数返回一个Deferred 吗?还是尽可能声明suspended fun 并在我所有的api 方法上调用deferred.await() 更好?
【问题讨论】:
标签: kotlin rx-java2 coroutine kotlin-coroutines