使用Kotlin的Kovenant我一直使用Deferred进入重复代码

时间:2016-09-19 03:24:03

标签: kotlin kovenant

当使用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中分享有趣问题的解决方案。

1 个答案:

答案 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()
        }
    }
}