【发布时间】:2021-03-08 01:02:11
【问题描述】:
这可能是一个非常愚蠢的问题,但我试图理解在 Finatra 的 HttpClient @987654321 中的此方法定义中使用 #flatMap 而不仅仅是 #map 背后的逻辑@:
def executeJson[T: Manifest](request: Request, expectedStatus: Status = Status.Ok): Future[T] = {
execute(request) flatMap { httpResponse =>
if (httpResponse.status != expectedStatus) {
Future.exception(new HttpClientException(httpResponse.status, httpResponse.contentString))
} else {
Future(parseMessageBody[T](httpResponse, mapper.reader[T]))
.transformException { e =>
new HttpClientException(httpResponse.status, s"${e.getClass.getName} - ${e.getMessage}")
}
}
}
}
当我可以只使用 #map 而拥有类似的东西时,为什么要创建一个新的 Future:
execute(request) map { httpResponse =>
if (httpResponse.status != expectedStatus) {
throw new HttpClientException(httpResponse.status, httpResponse.contentString)
} else {
try {
FinatraObjectMapper.parseResponseBody[T](httpResponse, mapper.reader[T])
} catch {
case e => throw new HttpClientException(httpResponse.status, s"${e.getClass.getName} - ${e.getMessage}")
}
}
}
这是否纯粹是一种风格上的差异,在这种情况下使用 Future.exception 只是更好的风格,而抛出几乎看起来像是一种副作用(实际上不是,因为它不会退出 Future 的上下文)还是后面有什么东西,比如执行顺序之类的?
Tl;博士: 在 Future 中抛出与返回 Future.exception 有什么区别?
【问题讨论】:
-
请注意,使用
Future.exception可能比抛出和捕获异常更快。 - 理想情况下,您永远不应该自己抛出异常,而应该在 Future 中使用exception之类的组合符来提升失败的值。 -
@LuisMiguelMejíaSuárez 谢谢,你有任何关于为什么它更快的指针/参考吗?
-
因为抛出和捕获异常很慢,而仅返回一个值与重新调整任何其他值一样快。见:mattwarren.org/2016/12/20/Why-Exceptions-should-be-Exceptional
-
@LuisMiguelMejíaSuárez 啊,这是有道理的。因为 Future 必须捕获异常。感谢您的链接
标签: scala functional-programming flatmap finatra twitter-util