1

このコードをリアクションスタイルでリファクタリングするのに誰かが助けてくれますか?Refactor ReactiveCrudRepository.deleteAll()。ブロック(ノンブロッキングコード)

userService.deleteAll().then().block(); 
userService.saveAll(Flux.just(candidate, tech, pm, hr)).then().block(); 

私は、この実装はthen(…)方法のonNext(…)によって簡素化することができると思います。 ありがとうございました。あなたは

結果 Publisherへの登録
Mono<Void> mono = userService.deleteAll() 
      .thenMany(userService.saveAll(Flux.just(candidate, tech, pm, hr))) 
      .then(); 

を探しているように見えます

+0

'then()。block()'の代わりに '.subscribe()'を使用します。 –

+0

@ M.Deinumあなたはその理由を説明できますか? – maystrovyy

+0

'block'thereはあなたのコードについて何も反応しないのでブロックされます... –

答えて

3

(この場合はMonoである)の実行を開始する自然な方法です。

反応性配列を設定したら、それを実行する方法を検討する時間です。シーケンスを購読するのは自然なアプローチ(.subscribe())ですが、実行を開始するのは当然ですが、そうするのが正当な理由がない限り、通常は自分のコード内で行うことではありません。ソースPublisher(あなたの場合はMongoDB/Couchbase/Cassandraドライバの1つです)に応じて、サブスクリプションは.subscribe()の呼び出しが終了した後も引き続き実行されるノンブロッキングプロセスを開始します。通常、インフラストラクチャ(コンテナ)はサブスクリプションをトリガーし、同期を処理します(.subscribe(Subscription)経由)。あなたのコードは次のようになります春WebFluxコントローラのコンテキストで:サーバーの応答の一部としてMono<Void>に渡すことにより

@PostMapping("…") 
public Mono<Void> save() { 

    Mono<Void> mono = userService.deleteAll() 
      .thenMany(userService.saveAll(Flux.just(candidate, tech, pm, hr))) 
      .then(); 

    return mono; 
} 

、あなたは実行のための反応順序を引き渡します。基底のコンテナはPublisherにサブスクライブし、サブスクリプションが終了するとすぐにHTTP応答を書き込みます(同期部分です)。

リアクティブシーケンスを自分で実行する場合は、自分で同期を処理する必要があります。 Mono.block()/Flux.block()は、隔離された環境で通話を同期させるのに便利な方法ですが、もう一度やってください。非常に良い理由は、周囲のコンテナを持たず、コードが大規模に実行されていない可能性があります。スレッドをブロックすると、実行が終了するまでスレッドがブロックされるため、リアクティブ実行モデルが提供するメリットが失われます。

最後の単語.deleteAll():データを削除または挿入してコンポーネントまたはデータベースの状態を初期化する必要がある場合があります。これらの初期化子はすべて、同期API内で実行されます(SpringのafterPropertiesSet()、JSR 250の@PostConstruct)。その特定の状況では、あなたは通常、同期を自分で処理したくないので、命令型APIに固執します。

関連する問題