文章目录
UniRx_2.2_Observable的使用
2.2.1 Observable的生成方法
- 使用 Subject
- 工厂方法
- UniRX提供的Observable
- Task(UniTask)进行变换
- 别的数据结构进行变换
2.2.2 Observable 可以利用的消息
-
OnNext()
using System; using UniRx; using UnityEngine; namespace Sample.Section2.Observables { public class MessageSample : MonoBehaviour { //剩余时间 [SerializeField] private float _countTimeSeconds = 30f; //到时间 进行通知的Observable public IObservable<Unit> OnTimeUpAsyncSubject => _onTimeUpAsyncSubject; //AsyncSubject (只发行一次消息的Subject) private readonly AsyncSubject<Unit> _onTimeUpAsyncSubject = new AsyncSubject<Unit>(); private IDisposable _disposable; private void Start() { //经过指定时间 发送消息 _disposable = Observable .Timer(TimeSpan.FromSeconds(_countTimeSeconds)) .Subscribe(_ => { //当 Timer 到了 //发送Unit型的消息 _onTimeUpAsyncSubject.OnNext(Unit.Default); _onTimeUpAsyncSubject.OnCompleted(); }); } private void OnDestroy() { //Observable 如果还在运作 停止 _disposable?.Dispose(); //Destory AsyncSubject _onTimeUpAsyncSubject.Dispose(); } } }
-
「_ =>」
UniRx 常常会使用Lambda表达式,用「_ =>」 来表示引数部分
this.UpdateAsObservable() .Where(_ => Input.GetKeyDown(KeyCode.Z)) .Subscribe(_ => Debug.Log("Z key is pushed."));
「_」表示 发行的OnNext消息内容是空的, 在OnNext消息「发行时」去处理程序,并不需要传递消息的内容
-
OnError()
当Observable内部处理中,异常发生时,发行,同时Observable 自动停止
-
OnOnCompleted()
当Observable不会再发送消息时 发行,Observable 自动停止。
2.2.3 销毁Observable的方法
-
OnCompleted() 消息发行时
using UniRx; var subject = new Subject<int>(); //订阅消息 subject.Subscribe( // OnNext x => Debug.Log(x), // OnComplete () => Debug.Log("OnCompleted!") ); subject.OnNext(1); subject.OnNext(2); subject.OnNext(3); // Subject 自身 OnComplete subject.OnCompleted(); // 销毁 subject.Dispose(); /* 结果 1 2 3 OnCompleted! */
-
OnError() 消息发行时
- 调用 Subject.OnError()
- 运算符处理时异常发生
using UniRx; var subject = new Subject<string>(); subject // string 变换 成 int 失败的化 就会发送异常 .Select(str => int.Parse(str)) .Subscribe( // OnNext x => Debug.Log(x), // OnError ex => Debug.LogError("Exception: " + ex.Message), // OnCompleted () => Debug.Log("OnCompleted!") ); subject.OnNext("1"); subject.OnNext("2"); //int.Parse 失败 异常发生 //Select 运算符 发送OnError消息 subject.OnNext("Three"); //错误发送了 Subscribe 停止 后续消息不会发送 subject.OnNext("4"); //但并不是Subject 本身发生异常 所以可以再次订阅 subject.Subscribe( x => Debug.Log(x), () => Debug.Log("Completed!")); subject.OnNext("Hello!"); subject.OnCompleted(); subject.Dispose(); /* 结果 1 2 例外が発生しました:Input string was not in the correct format Hello! Completed! */
-
Subscribe()的Dispose()执行时
-
IObservable 订阅时 Subcribe()的返回值 是IDisposable Interface
IDisposable 是 释放 object的接口
namespace System { public interface IDisposable { void Dispose(); } }
-
Subcribe()的IDisposable 的Dispose()执行时,可以单独中断这个订阅
using UniRx; var subject = new Subject<int>(); // 同一个Subject 订阅三次 生成了三个Observable IDisposable disposableA = subject .Subscribe(x => Debug.Log("A:" + x)); // A IDisposable disposableB = subject .Subscribe(x => Debug.Log("B:" + x)); // B IDisposable disposableC = subject .Subscribe(x => Debug.Log("C:" + x)); // C //发行消息 subject.OnNext(100); // 执行 A 的 Dispose disposableA.Dispose(); Debug.Log("---"); // 再发行消息 subject.OnNext(200); // 结束 subject.OnCompleted(); // Subject 自身 release subject.Dispose(); /* A:100 B:100 C:100 --- B:100 C:100 */
-
-
StreamSource (数据流) Dispose()执行时
- 数据流 就是数据源头 如Subject ReactiveProperty
- 由这个数据生成的所有Observable 都会销毁
- IObserver.OnCompleted() 不执行
- await 的时候 会被中断
2.2.4 AddTo() 方法
-
UniRx 对IDisposable 接口的扩展方法
-
一开始注册一下,在特定的时机执行
- GameObject OnDestroy()执行时
- CompositeDisposable 的Dispose() 执行时
//GameObject作为注册对象 public static T AddTo<T>( this T disposable, GameObject gameObject ) where T : IDisposable // Component 作为注册对象 和GameObject 相同 public static T AddTo<T>( this T disposable, Component gameObjectComponent ) where T : IDisposable // CompositeDisposable 作为注册对象 public static T AddTo<T>( this T disposable, ICollection<IDisposable> container ) where T : IDisposable // 上面两个都作为注册对象 public static T AddTo<T>( this T disposable, ICollection<IDisposable> container, GameObject gameObject ) where T : IDisposable
-
例
using UniRx; using UnityEngine; namespace Samples.Section2.Observables { public class AddToSample : MonoBehaviour { private void Start() { // 每5 帧发送一次消息 Observable.IntervalFrame(5) .Subscribe(_ => Debug.Log("Do!")) //当这个GameObject OnDestroy时 自动Dispose() .AddTo(this); } } }