问题是,您在承诺链外泄漏了异常。想象一下这段代码:
fun makeMyPromise(): Promise<Int, Exception> {
val result: Int = callSomeCalculation() // <--- exception occurs here
val deferred = deferred<Int, Exception>()
deferred.resolve(result)
return deferred.promise
}
这基本上就是你的代码在第一行所做的。如果抛出异常,该方法将退出,并且不会调用deferred.reject
。将代码更改为:
fun makeMyPromise(): Promise<Int, Exception> {
val deferred = deferred<Int, Exception>()
try {
val result: Int = callSomeCalculation() // <--- exception occurs here
deferred.resolve(result)
} catch (ex: Exception) {
deferred.reject(ex)
}
return deferred.promise
}
会更正确,并捕捉到您的异常。它确保没有任何东西可能从承诺链泄漏。
因此,回到您的原始代码,您的callSomeCalculation()
发生在Promise.of()
方法被调用之前,并且它不可能提供这种保护。它发生在Kovenant有一个想法,你甚至创造了一个承诺。所以你需要一个新的Promise.of(lambda)
方法来接受一个可以完全防止这种泄漏的代码块。
这是一个新的Promise.of(lambda)
扩展功能:
fun <V> Promise.Companion.of(codeBlock:() -> V): Promise<V, Exception> {
val deferred = deferred<V, Exception>()
try {
deferred.resolve(codeBlock())
}
catch (ex: Exception) {
deferred.reject(ex)
}
return deferred.promise
}
这将作为:因为现在的代码块被传递到
Promise.of { callSomeCalculation() } <-- sometimes throws exception
.then { ... }
.then { ... }
.fail { ex -> log.error(ex) } <-- exception ALWAYS logged!
通知改为{}
括号中的括号()
Promise.of
方法,并包装了异常处理,防止任何泄漏。您现在将在后面的fail { .. }
块中看到您的异常记录。
这似乎是使用'task'方法的替代方法:http://kovenant.komponents.nl/api/core_usage/#task。你能解释什么时候应该使用而不是'task'吗? – Ilya
同步(Promise.of与异步(任务)调度代码,但要确保计算的值不会泄漏异常 –
另一件与我提出的Promise.of'重载相关的事情是,现在它的行为意想不到的时候,想要承诺功能类型'Promise <() -> V>',但获得'Promise'而不是 –
Ilya