これは本当にばかげた質問かもしれませんが、Finatra の HttpClient定義のこのメソッド定義で#mapだけでなく、# flatMap を使用する背後にあるロジックを理解しようとしています。
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 を返すことの違いは何ですか?