オペレーターは、観察可能なオブジェクトを変換する問題を解決するために使用されます。オペレーターは、Observableと最終サブスクライバーの間で観察可能なイベントを変更するために使用されます。 Rxjavaは多くの有用な演算子を提供します。
たとえば、マップ演算子は、あるイベントを別のイベントに変換するために使用されます。
observable.just( "hello、world!").map(new func1 <string、string>(){@override public string call(string s){return s + "-dan";}}).subscribe(s-> system.out.println(s)); Lambdaを使用することは単純化できます
observable.just( "hello、world!").map(s-> s + "-dan").subscribe(s-> system.out.println(s));
かっこいいですか? MAP()演算子は、観察可能なオブジェクトを変換するために使用されます。マップ演算子は、観測可能なオブジェクトを返し、チェーンコールを実装し、マップ演算子を観察可能なオブジェクトで複数回使用し、最後に最も単純なデータがサブスクライバーオブジェクトに渡されます。
マップオペレーターがアドバンスされました
マップ演算子のさらに興味深いのは、観測可能なオブジェクトによって返されたタイプを返す必要がないことです。マップ演算子を使用して、新しいデータ型を発する観測可能なオブジェクトを返すことができます。
たとえば、上記の例では、サブスクライバーは返された文字列を気にしませんが、文字列のハッシュ値が必要です。
observable.just( "hello、world!").map(new func1 <string、integer>(){@override public integer call(string s){return s.hashcode();}}).subscribe(i-> system.out.println(integer.tostring(i));とても面白いですよね?最初の観測可能な人は文字列を返し、最終サブスクライバーは整数を受け取ります。もちろん、Lambdaを使用すると、コードをさらに簡素化できます。
observable.just( "hello、world!").map(s-> s.hashcode()).subscribe(i-> system.out.println(integer.tostring(i)));
前述のように、購読することが少ないほど良いです。別のマップ演算子を追加しましょう。
observable.just( "hello、world!").map(s-> s.hashcode()).map(i-> integer.tostring(i)).subscribe(s-> system.out.println(s));
確信していませんか?
私たちの例はあなたを納得させるにはあまりにも簡単だと思いますか?次の2つのポイントを理解する必要があります。
1.観察可能およびサブスクライバーは何でもできます
観察可能はデータベースクエリになる可能性があり、サブスクライバーを使用してクエリの結果を表示します。観察可能は、画面上のクリックイベントであり、サブスクライバーを使用してクリックイベントに応答します。 Observableはネットワークリクエストであり、サブスクライバーを使用してリクエスト結果を表示します。
2。観察可能およびサブスクライバーは、中間変換プロセスとは無関係です。
任意の数のマップを、観察可能なものとサブスクライバーの間に追加または減少させることができます。システム全体が非常に組み合わせることができ、操作データは非常に単純なプロセスです。
例
1。準備
このような方法があるとします:
この方法は、入力文字列(AHHA、検索エンジン)に基づいてWebサイトのURLリストを返します
Observable <list <string >> query(string text);
次に、文字列を照会して結果を表示できる堅牢なシステムを構築したいと考えています。前のブログの内容に基づいて、次のコードを書くことができます。
query( "hello、world!").subscribe(urls-> {for(string url:urls){system.out.println(url);}});もちろん、上記のコードによりデータフローを変更する能力が失われたため、この種のコードは許容できません。各URLを変更したい場合は、サブスクライバーでのみ行うことができます。このようなクールなMAP()オペレーターは使用しませんでした! ! !
もちろん、マップ演算子を使用できます。マップの入力はURLSリストです。処理するときは、それぞれを通過する必要がありますが、これも非常に苦痛です。
幸いなことに、観察可能な.from()メソッドもあります。これは、入力としてコレクションを受信し、一度にサブスクライバーに要素を出力します。
observable.from( "url1"、 "url2"、 "url3").subscribe(url-> system.out.println(url));
この方法を今すぐシーンに使用しましょう:
query( "hello、world!").subscribe(urls-> {obervable.from(urls).subscribe(url-> system.out.println(url));});
各ループは削除されていますが、コードはまだ乱雑に見えます。複数のネストされたサブスクリプションは、醜くて変更するのが難しいだけでなく、さらに真剣に、まだ言及していないRXJavaの機能のいくつかを破壊します。
2。改善
救い主はここにいます、彼はフラットマップ()です。
Observable.flatmap()は、観測可能な出力を入力として受信し、同時に別の観測可能な出力を受信します。コードを直接見る:
Query( "Hello、world!").flatmap(new func1 <list <string>、oboverride public observable <string> call(list <string> urls){return observable.from(urls);}}).subscribe(url-> system.out.println(url));ここでは、機能コード全体を投稿して、何が起こっているのかを理解できるようにします。 Lambdaを使用すると、コードの長さを大幅に簡素化できます。
query( "hello、world!").flatmap(urls-> observable.from(urls)).subscribe(url-> system.out.println(url));
flatmap()は奇妙に見えますか?なぜ別の観察可能なものを返すのですか?フラットマップを理解する重要なポイントは、フラットマップからの新しい観測可能な出力がまさにサブスクライバーで受け取りたいものであることです。これで、サブスクライバーはリスト<String>を受信しなくなりましたが、代わりに、observable.from()の出力のように、列の単一文字列を受信します。
この部分は、私が最初にrxjavaを学んだときの最も難しい部分でもあります。突然気づいたら、RXJavaの質問の多くが解決されました。
3。それはより良いことができます
flatmap()は本当により良いアイデアではありません。返品したいオブジェクトを返すことができます。
たとえば、次の方法:
//ウェブサイトのタイトルを返し、404の場合は、null butrenvable <string> getTitle(string url)を返します。
前の例に従って、今ではURLを印刷したくありませんが、代わりに受け取った各Webサイトのタイトルを印刷します。問題は、私の方法が一度に1つのURLのみを渡すことができ、戻り値は文字列ではなく、文字列を出力する観察的オブジェクトであることです。 flatmap()を使用すると、この問題を解決できます。
Query( "Hello、world!").flatmap(urls-> observable.from(urls)).flatmap(new func1 <string、oboverride public observable <string> call(string gettitle(url);}
4。ラムダを使用:
query( "hello、world!").flatmap(urls-> Observable.from(urls)).flatmap(url-> gettitle(url)).subscribe(title-> system.out.println(title));
信じられないほど感じませんか?実際に複数の独立した方法を組み合わせて、観察可能なオブジェクトを一緒に返すことができます!とてもハンサム!
それ以上に、私は2つのAPIの呼び出しを鎖でつながれた呼び出しに組み合わせました。できるだけ多くのAPI呼び出しをリンクできます。すべてのAPI呼び出しを同期し、すべてのAPI呼び出しのコールバック結果をデータに組み合わせて表示することがどれほど苦痛であるかを誰もが知っておく必要があります。ここでは、コールバックHell(マルチレイヤーネストコールバックを使用して、コードの読み取りと維持を困難にする)を避けました。これで、すべてのロジックがこのシンプルなレスポンシブコールにまとめられています。
5.リッチオペレーター<BR />これまでのところ、2人のオペレーターと接触しており、RXJAVAにはより多くのオペレーターがいるので、他のオペレーターを使用してコードを改善するにはどうすればよいですか?
URLが存在しない場合、gettitle()はnullを返します。 「null」を出力したくないので、返されたタイトルリストからnull値を除外できます!
query( "Hello、world!").flatmap(urls-> observable.from(urls)).flatmap(url-> gettitle(url)).filter(title-> title!= null).subscribe(> system.out.out.println(title));
filter()は、入力と同じ要素を出力し、チェック基準を満たしていないものをフィルタリングします。
最大5つの結果しか必要ない場合:
Query( "Hello、world!").flatmap(urls-> Observable.from(urls)).flatmap(url-> gettitle(url)).filter(title-> title!= null).take(5).subscribe(title-> system.out.out.println(title.out));
Take()は、結果の最大数を出力します。
印刷する前に各タイトルをディスクに保存したい場合:
Query( "Hello、world!").flatmap(urls-> observable.from(urls)).flatmap(url-> gettitle(url)).filter(title-> title!= null)。
DOONNEXT()を使用すると、ここでタイトルを保存するなど、一度に要素を出力する前に、いくつかの余分なことを行うことができます。
ここでデータフローを操作するのがどれほど簡単かを見るのは簡単ですか?好きなだけ操作を追加したり、コードを台無しにしたりすることはできません。
RXJAVAには多数のオペレーターが含まれています。オペレーターの数は少し怖いですが、どのオペレーターを使用できるかを知ることができるように、1つずつチェックアウトする価値があります。これらのオペレーターを理解するのに時間がかかる場合がありますが、理解すれば、RXJavaの力を完全に把握できます。
カスタムオペレーターを書くこともできます!このブログは、オペレーターをカスタマイズするつもりはありません。必要に応じて、自分でグーグルで検索してください。
気分はどうですか?
まあ、あなたは懐疑論者であり、説得するのは難しいので、なぜこれらのオペレーターを気にかけますか?
なぜなら、オペレーターはデータストリームに何かをすることができるからです。
一連のオペレーターをリンクすると、複雑なロジックが達成できます。コードは、組み合わせることができる一連のスニペットに分類されます。これは、リアクティブ関数プログラミングの魅力です。使用すればするほど、プログラミング思考を変えることができます。
さらに、RXJavaはデータを簡単に処理できるようにします。最後の例では、2つのAPIを呼び出し、APIで返されるデータを処理し、ディスクに保存します。しかし、私たちのサブスクライバーはこれを知らないので、観察可能な<string>オブジェクトを受信していると考えています。優れたパッケージもコーディングの利便性をもたらします!
3番目の部分では、データの処理に直接使用されていないエラー処理や並行性など、RXJavaの他のクールな機能を紹介します。