2011/11/29 追記 Doメソッドの多用に注意する旨を追記しました。 2011/12/10 注意点を修正しました。
- Reactive Extensions再入門 その1
- Reactive Extensions再入門 その2「IObservableインターフェースとIObserverインターフェース」
- Reactive Extensions再入門 その3「IObservableのファクトリメソッド」
- Reactive Extensions再入門 その4「Timer系のファクトリメソッド」
- Reactive Extensions再入門 その5「HotとCold」
- Reactive Extensions再入門 その6「HotなIObservableを作成するファクトリ」
- Reactive Extensions再入門 その7「LINQスタイルの拡張メソッド」
- Reactive Extensions再入門 その8「SkipとTakeメソッド」
- Reactive Extensions再入門 その9「Skip + Take + Repeat = ドラッグ」
はじめに
軽いRxネタで息抜きです。今回はDoです。恐らく?一番簡単なんじゃないかと思います。
Doメソッド
ここでは、Doメソッドについて説明します。DoメソッドはIObservable
var subject = new Subject<int>(); subject // 途中に処理を挟む .Do(i => Console.WriteLine("Do : {0}", i)) // 購読(購読しないとOnNextをしても値が流れないね) .Subscribe(i => Console.WriteLine("OnNext : {0}", i)); // 値の発行 subject.OnNext(1); subject.OnNext(2); subject.OnNext(3);
このコードを実行すると、Subscribeで値を購読している処理の前にDoの処理が行われていることが確認出来ます。
>|||
Do : 1
OnNext : 1
Do : 2
OnNext : 2
Do : 3
OnNext : 3
|
Doメソッドには、OnNextに対応する処理だけではなくOnErrorやOnCompleted時の処理を指定することも出来ます。このオーバーロードはSubscribeと同じでOnErrorにはAction
var subject = new Subject<int>(); subject // 途中に処理を挟む .Do( i => Console.WriteLine("Do : OnNext : {0}", i), ex => Console.WriteLine("Do : OnError : {0}", ex), () => Console.WriteLine("Do : OnCompleted")) // 購読(購読しないとOnNextをしても値が流れないね) .Subscribe( i => Console.WriteLine("OnNext : {0}", i), ex => Console.WriteLine("OnError : {0}", ex), () => Console.WriteLine("OnCompleted")); // 値の発行 subject.OnNext(1); subject.OnError(new Exception());
実行結果を下記に示します。
Do : OnNext : 1 OnNext : 1 Do : OnError : System.Exception: 種類 'System.Exception' の例外がスローされました。 OnError : System.Exception: 種類 'System.Exception' の例外がスローされました。
最後にOnCompletedの場合のコード例を下記に示します。
var subject = new Subject<int>(); subject .Do( i => Console.WriteLine("Do : OnNext : {0}", i), ex => Console.WriteLine("Do : OnError : {0}", ex), () => Console.WriteLine("Do : OnCompleted")) // 購読(購読しないとOnNextをしても値が流れないね) .Subscribe( i => Console.WriteLine("OnNext : {0}", i), ex => Console.WriteLine("OnError : {0}", ex), () => Console.WriteLine("OnCompleted")); // 値の発行 subject.OnNext(1); subject.OnCompleted();
実行結果を下記に示します。
Do : OnNext : 1 OnNext : 1 Do : OnCompleted OnCompleted
このように、Doメソッドを使うとIObservable
Doメソッド使用時の注意点
DoメソッドはReactive Extensionsの処理の中に任意のアクションを実行できるという便利なメソッドですが、本来は外部に対して副作用を起こさないReactive Extensionsの処理の中で副作用を起こすためのメソッドになります。そのため、Doメソッドの利用は必要最低限にとどめてください。Doメソッド以外の代替メソッドがある場合はそれを使用するように心がけましょう。また、複数のDoメソッドでフラグ変数を共有して挙動を変えるなど、動作が複雑化してきた場合は、一度立ち止まり本当にそれが必要か考えるようにすることをお勧めします。