ActionやFuncからObservableを作る方法です。
Observable.ToAsync
Observable.ToAsync()を使うとOnNext()が一回だけ呼ばれてそれと同時にOnCompleted()が呼ばれるようなObservableを簡単に作れます。
Observable.ToAsync(() => { // 1秒遅延させる Thread.Sleep(1000); // 今の時間を流す // OnCompletedもここで呼ばれる return System.DateTime.Now; }) .Invoke() .Subscribe(x => Debug.Log(x));
ToAsync()はIObservableを返すFuncを返してくるので、Invoke()することでIObservableを得られます。
Observable.ToAsync(() => { Thread.Sleep(1000); return System.DateTime.Now; }) .Invoke(); // SubscribeしなくてもInvokeすれば処理が開始される
Invoke()の時点でストリームが生成されるため、下記の2パターンで挙動が変わるので注意が必要です。
// 同じObservableを購読するのでThread.Sleep()は1回だけ行われる var observable = Observable.ToAsync(() => { Thread.Sleep(1000); return System.DateTime.Now; }) .Invoke(); observable.Subscribe(x => Debug.Log(x)); observable.Subscribe(x => Debug.Log(x)); // Observableが2つ作られてそれぞれを購読するのでThread.Sleep()は2回行われる var observableFunc = Observable.ToAsync(() => { Thread.Sleep(1000); return System.DateTime.Now; }); observableFunc.Invoke().Subscribe(x => Debug.Log(x)); observableFunc.Invoke().Subscribe(x => Debug.Log(x));
Observable.Start
Observable.Start()で生成したObservableをSubscribe()すると、
Observable.ToAsync()のあとすぐInvoke()したのと同じ効果が得られます。
var observable = Observable.Start(() => { Debug.Log("debug"); Thread.Sleep(1000); return System.DateTime.Now; }); // ストリームは2個生成される observable.Subscribe(x => Debug.Log(x)); observable.Subscribe(x => Debug.Log(x)); // 上と下は同等の処理 var observableFunc = Observable.ToAsync(() => { Debug.Log("debug2"); Thread.Sleep(1000); return System.DateTime.Now; }); // ストリームは2個生成される observableFunc.Invoke().Subscribe(x => Debug.Log(x)); observableFunc.Invoke().Subscribe(x => Debug.Log(x));
Observable.FromEvent
Observable.FromEventはいろんなActionやFuncを柔軟にObservable化できます。
using UniRx; using UnityEngine; public class UniRxExample : MonoBehaviour { private event System.Action<float> _onTakeDamage; private void Start() { Observable.FromEvent<float> ( h => _onTakeDamage += h, h => _onTakeDamage -= h ); } }