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 ); } }