从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 { ... } ,使延期,而是照顾所有额外的工作?

注意: 这个问题是由作者故意编写和回答的( 自我回答问题 ),所以在SO中共享有趣问题的解决方案。

您可以使用与扩展函数Lock.withLock()Closeable.use()相同的模式,即使用您想要的处理来包装lambda表达式,并很好地推断类型以避免Deferred实例的样板。

函数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() } } }