这可能是一个非常愚蠢的问题,但我试图了解在 Finatra 的 HttpClient定义中的此方法定义中使用#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; dr:在 Future 中抛出与返回 Future.exception 有什么区别?