web-dev-qa-db-ja.com

Flux.createとFlux.generateの違い

違いは何ですか - Flux.create および Flux.generate ?私は、理想的には使用例を使用して、どちらを使用すべきかを理解しています。

15
JJ Zabkar

要するに:

_Flux::create_はアプリの状態の変化に反応しませんが、_Flux::generate_は反応します。


ロングバージョン

_Flux::create_

アプリの状態やpipeline(your pipelineの状態に影響されない複数の(0 ...無限大)値を計算する場合に使用します。 = ==続く操作のチェーン _Flux::create_ == 下流)。

どうして? _Flux::create_に送信したメソッドが要素を計算し続ける(または何もしない)ためです。 downstreamは、必要な要素(elements == next signal)の数を決定し、彼が追い付かない場合は、既に放出されている要素が削除/バッファリングされます。一部の戦略では(デフォルトではdownstreamがさらに要求するまでバッファリングされます)。

最初の最も簡単な使用例は、理論的にはコレクションに合計して、各要素を取得してそれで何かを実行できる値を出力する場合です。

_Flux<String> articlesFlux = Flux.create((FluxSink<String> sink) -> {
    /* get all the latest article from a server and
       emit them one by one to downstream. */
    List<String> articals = getArticalsFromServer();
    articals.forEach(sink::next);
});
_

ご覧のとおり、_Flux.create_は、ブロッキングメソッド(getArticalsFromServer)と非同期コードの間の相互作用に使用されます。

_Flux.create_には他にも使用例があります。


_Flux::generate_

_Flux.generate((SynchronousSink<Integer> synchronousSink) -> {
        synchronousSink.next(1);
    })
    .doOnNext(number -> System.out.println(number))
    .doOnNext(number -> System.out.println(number + 4))
    .subscribe();
_

出力は_1 5 1 5 1 5................forever_になります

各呼び出しで _Flux::generate_に送信したメソッドの=、synchronousSinkonSubscribe onNext? (onError | onComplete)?のみを発行できます。

つまり、_Flux::generate_は計算して出力オンデマンドになります。いつ使用すべきですか?使用できない可能性のある要素を計算するのにコストがかかりすぎる場合downstreamまたは、発生するイベントがアプリの状態またはpipelineの状態に影響される(あなたのパイプライン ==来る操作の連鎖 _Flux::create_ == 下流)。

たとえば、トレントアプリケーションを構築している場合は、リアルタイムでデータのブロックを受信して​​います。 _Flux::generate_を使用して複数のスレッドにタスク(ダウンロードするブロック)を与え、一部のスレッドが要求した場合にのみ、ダウンロードするブロックを_Flux::generate_内で計算します。だからあなたは持っていないブロックだけを放出するでしょう。 _Flux::create_を使用した同じアルゴリズムは失敗します。これは、_Flux::create_が所有していないすべてのブロックを出力し、一部のブロックがダウンロードに失敗した場合に問題が発生するためです。 _Flux::create_はアプリの状態の変化に反応しませんが、_Flux::generate_は反応します。

16
Stav Alfi