UniRx_UniTask_学习记录_2.2_Observable的使用

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);
            }
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值