FluxとかMonoの勉強しようと思って、よこみちにそれて。
その流れで、Java8にCompletableFutureなるものがあることを知り。
この章だけ読んだ。
面白かったのでまた別の機会にまとめをメモしときたいなと思いつつ。今日は、疑問が。
thenApplyとthenCompose
thenApplyにCompletableFutureを返すConsumer渡すのと、thenCompose使うのの違いってなんなんだろう??
— Mitsuyuki.Shiiba (@bufferings) June 7, 2016
@bufferings thenApplyのConsumerでCompletableFuture<U>返したらthenApplyの戻り値はCompletableFuture<CompletableFuture<U>>にならない?
— うらがみ (@backpaper0) June 7, 2016
確かに!ふむふむ。
そして、混乱
書籍のサンプルコードはこんな流れなんだけど。
shops.stream() // 店舗の価格APIを非同期で呼び出し .map(shop -> CompletableFuture.supplyAsync(() -> shop.getPrice(product))) // 結果の文字列をパースして価格を取得 .map(future -> future.thenApply(Quote::parse)) // 割引APIを非同期で呼び出して、価格から割引結果を取得 .map(future -> future.thenCompose( quote -> CompletableFuture.supplyAsync(() -> Discount.applyDiscount(quote)))) .collect(toList());
この、thenComposeを使う代わりに、thenApplyで同期的に呼び出しても、いいんじゃないか?と思ってしまって混乱。既に、最初のgetPriceのところで別のスレッドで実行されるようになってるから、そのままそのスレッドでやってしまえば・・・と思ったんだけど。thenComposeする利点ってなんだろう?
もうちょっと考えてみる。
追記:そしてうらがみさんに色々教えてもらいました!(∩´∀`)∩ワーイ
色々教えてもらってすっきりしました!ありがとうございました!
@bufferings サンプルコード無視して言うけど、thenComposeの使いどころのひとつは、すでにCompletableFutureを返すAPIがあって、それと組み合わせるときかなー、と思いました。
— うらがみ (@backpaper0) 2016年6月7日
@backpaper0 そう。結局thenComposeの使いどころが腑に落ちてない感じする。どうしてすでにCompletableFuture持ってるのにもういっこ生やしたいんだろう?
— Mitsuyuki.Shiiba (@bufferings) 2016年6月7日
@bufferings 生やしたくて生やすんじゃなくて、生やさざるを得ない状況用と思ってるー。
— うらがみ (@backpaper0) 2016年6月8日
@backpaper0 ふむふむ。どういうときに生やさざるを得ない状況になるのかなー?と思った。
— Mitsuyuki.Shiiba (@bufferings) 2016年6月8日
…thenComposeで生やしといて、別のことをやった後に結果を受け取るのかな。
@bufferings 生やさざるを得ない状況は、朝にリプした通り、すでに存在するAPIがCompletableFutureを返すようになっていて、そのAPIを利用する、といったときかな。
— うらがみ (@backpaper0) 2016年6月8日
@bufferings そのようなAPIを使いたいとして、逆にthenComposeを使わず同じことが簡単に実現できるか?を考えると良いかも。
— うらがみ (@backpaper0) 2016年6月8日
@backpaper0 うおー!なんか分かったような気がします!
— Mitsuyuki.Shiiba (@bufferings) 2016年6月8日
@bufferings ブログちゃんと読んだー。thenApply・thenComposeとスレッドは関係なくて、非同期で実行したいならthenApplyAsyncが使える。
— うらがみ (@backpaper0) 2016年6月8日
@bufferings その上で、ブログに書かれたサンプルコードを読んでみたけど確かにthenComposeする必要はなさそうに思う。そういうAPIがあるんだよ、って見せたいならともかく、それ以外の理由はちょっと思い浮かばないなー。
— うらがみ (@backpaper0) 2016年6月8日
@backpaper0 @bufferings サンプルコード変な気がしますね。あと、サーバーサイドでやるな危険的なコードだ
— Toshiaki Maki (@making) 2016年6月8日
@backpaper0 @making 危険なの?
— Mitsuyuki.Shiiba (@bufferings) 2016年6月8日
@bufferings @making Javaのウェブアプリはコンテナがスレッド管理しているので、Executorを渡すxxxAsyncメソッドを使わないといけないですねー。
— うらがみ (@backpaper0) 2016年6月8日
@backpaper0 @making おお!すみません。そこ実際のサンプルコードにはあったんだけど、読みにくいかなとおもって消しちゃいました!(ノ)'ω`(ヾ)
— Mitsuyuki.Shiiba (@bufferings) 2016年6月8日
そうかー。すっきりしたー!
— Mitsuyuki.Shiiba (@bufferings) 2016年6月8日