当使用Kotlin的Kovenant时,我最终会得到许多代码模式:
fun foo(): Promise<SomeResultType, Exception> {
val deferred = deferred<SomeResultType, Exception>()
try {
// bunch of work that deferred.resolve() or deferred.reject()
}
catch (ex: Exception) {
deferred.reject(ex)
}
return deferred.promise
}
我知道我可以使用task { ... }
来实现异步承诺,并且会处理其中的一些,但是当我已经异步或将适配器写入其他异步类时,我想使用Deferred
实例
是否有类似task { ... }
的内容而是延迟而是负责所有额外的工作?
注意: 此问题是由作者(Self-Answered Questions)故意编写和回答的,因此可以在SO中分享有趣问题的解决方案。
答案 0 :(得分:3)
您可以使用与扩展函数Lock.withLock()
和Closeable.use()
相同的模式,即使用您想要的处理包装lambda并很好地推断类型以避免在{{3}周围使用样板实例。
函数withDeferred
:
fun <T : Any?> withDeferred(codeBlock: Deferred<T, Exception>.() -> Unit): Promise<T, Exception> {
val deferred = deferred<T, Exception>()
try {
deferred.codeBlock()
}
catch (ex: Exception) {
deferred.reject(ex)
}
return deferred.promise
}
然后可以用作:
fun foo(): Promise<SomeType, Exception> {
return withDeferred {
// bunch of work that calls resolve() or reject()
}
}
然而,当你直接链接承诺时,它并不那么漂亮。如果您没有可以推断出Deferred
实例的泛型的明确类型,则会出现问题。因此,链接这些可能需要在呼叫站点指定泛型,例如:
fun foo(): Promise<SomeType, Exception> {
return withDeferred<PreviousType> {
// bunch of work that calls resolve(PreviousType) or reject()
} bind { previous ->
withDeferred<SomeType> {
// bunch of work that calls resolve(SomeType) or reject()
}
}
}