3

これは本当にばかげた質問かもしれませんが、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 を返すことの違いは何ですか?

4

2 に答える 2