gpt4 book ai didi

kotlin - 修改延迟结果

转载 作者:IT老高 更新时间:2023-10-28 13:39:23 25 4
gpt4 key购买 nike

给定一个返回模型的 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()

最佳答案

如果你遵循异步风格的编程,那就是编写返回 Deferred<T> 的函数。 ,那么你可以定义异步函数 getDummyAge像这样:

fun getDummyAge(): Deferred<Int> = async { getDummy().await().age }

但是,这种编程风格在 Kotlin 中一般不推荐。惯用的 Kotlin 方法是定义一个暂停扩展函数 Call<T>.await()带有以下签名:

suspend fun <T> Call<T>.await(): T = ... // more on it later

并用它来写挂起函数 getDummy返回 Dummy 的结果直接键入 而不将其包装成延迟:

suspend fun getDummy(): Dummy = api.getDummy().await()

在这种情况下,您可以简单地编写暂停函数 getDummyAge :

suspend fun getDummyAge(): Int = getDummy().age

对于改造调用,您可以实现 await像这样的扩展:

suspend fun <T> Call<T>.await(): T = suspendCancellableCoroutine { cont ->
cont.invokeOnCompletion { cancel() }
enqueue(object : Callback<T> {
override fun onFailure(call: Call<T>?, t: Throwable) {
cont.resumeWithException(t)
}

override fun onResponse(call: Call<T>?, response: Response<T>) {
if (response.isSuccessful) {
cont.resume(response.body()!!)
} else {
cont.resumeWithException(HttpException(response))
}
}
})
}

如果你想了解更多关于异步函数和挂起函数在风格上的差异,那么我建议观看 Introduction to Coroutines来自 KotlinConf 2017。如果您喜欢简短的阅读,那么 this section from the design document也提供了一些见解。

关于kotlin - 修改延迟结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49762153/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com