12.UniRx序列(FromEvent、FromEventPattern、Where、WhenAll、Never)

FromEvent()
FromEventPattern()
Where()
WhenAll()
Never<>()

FromEvent

將C#事件轉換成流,當事件有回調的時候,通知到流,包括event、delegate及其衍生的回調字段,圖解
在這裏插入圖片描述
執行結果
在這裏插入圖片描述

代碼示例

public class No12_Mixed2 : MonoBehaviour
{
    public event EventHandler<IntEventArgs> mEventArgCallback;

    public class IntEventArgs : EventArgs
    {
        public int Property { get; set; }
    }

    void Start()
    {
        void AddHandler(EventHandler<IntEventArgs> handler)
        {
            mEventArgCallback += handler;
        }

        void RemoveAction(EventHandler<IntEventArgs> handler)
        {
            mEventArgCallback -= handler;
        }

        var fromEvent = Observable.FromEvent<EventHandler<IntEventArgs>, IntEventArgs>(EventMethod,
            AddHandler, 
            RemoveAction);
        var disposable = fromEvent.Subscribe(Next, Error, Complete);
        disposable.AddTo(gameObject);

        IntEventArgs args = new IntEventArgs();
        args.Property = 100;

        mEventArgCallback(this, args);
    }

    EventHandler<IntEventArgs> EventMethod(Action<IntEventArgs> action)
    {
        void Handler(object sender, IntEventArgs e)
        {
            action(e);
        }

        return Handler;
    }

    void Next(IntEventArgs args)
    {
        Debug.LogFormat("回調事件觸發了,參數值:{0}", args.Property);
    }

    void Error(Exception ex)
    {
        Debug.LogException(ex);
    }

    void Complete()
    {
        Debug.LogFormat("Complete");
    }

}

代碼解析

EventHandler是C#系統內置的一個事件處理類,指定一個參數類型;參數類型由系統的EventArgs來派生;FromEvent需要指定兩個包裝類型,第一個是代理,第二是參數;一般的寫法都是按照EventHandler和EventArgs的方式;EventMethod,東EventHandler過來的數據經過什麼來派生,由於EventHandler的構造方式指定是object和EventArgs,返回的是一個指針函數,在函數裏面將需要的數據返回到流那邊去處理;AddHandler和RemoveHandler分別是對原始的回調進行訂閱和取消訂閱,通過流的Subscribe和Disposable方法來進行訂閱和移除。


FromEventPattern

和FromEvent功能一樣,不過FromEventPattern會將結果全部交付到流,包含調用對象和參數

執行結果

在這裏插入圖片描述

代碼示例

public class No12_Mixed2 : MonoBehaviour
{
    public event EventHandler<IntEventArgs> mEventArgCallback;

    public class IntEventArgs : EventArgs
    {
        public int Property { get; set; }
    }

    void Start()
    {
        void AddHandler(EventHandler<IntEventArgs> handler)
        {
            mEventArgCallback += handler;
        }

        void RemoveAction(EventHandler<IntEventArgs> handler)
        {
            mEventArgCallback -= handler;
        }

        var fromEvent = Observable.FromEventPattern<EventHandler<IntEventArgs>, IntEventArgs>(ConversionFunc,
            AddHandler, 
            RemoveAction);
        var disposable = fromEvent.Subscribe(Next, Error, Complete);
        disposable.AddTo(gameObject);

        IntEventArgs args = new IntEventArgs();
        args.Property = 100;

        mEventArgCallback(this, args);
    }

    private EventHandler<IntEventArgs> ConversionFunc(EventHandler<IntEventArgs> @event)
    {
        return @event.Invoke;
    }

    void Next(EventPattern<IntEventArgs> args)
    {
        Debug.LogFormat("回調事件觸發了,條用對象:{0} 參數值:{1}", args.Sender, args.EventArgs.Property);
    }

    void Error(Exception ex)
    {
        Debug.LogException(ex);
    }

    void Complete()
    {
        Debug.LogFormat("Complete");
    }

}

代碼解析

由於FromEventPattern是直接將方法invoke,保留了方法的所有參數,在流Next的時候,EventPattern可以獲取原始的object調用者對象和傳入的參數值。


Where

篩選一個原始數據或者達到某一種符合的判定條件,圖解

在這裏插入圖片描述

執行結果

在這裏插入圖片描述

代碼示例

public class No12_Mixed2 : MonoBehaviour
{ 
    void Start()
    {
        var update = Observable.EveryUpdate();
        var @where = update.Where(_ => Input.GetMouseButtonDown(0));
        @where.Subscribe(Next, Error, Complete);
    }

    void Next(long frame)
    {
        Debug.LogFormat("點擊事件觸發了,發生在{0}幀", frame);
    }

    void Error(Exception ex)
    {
        Debug.LogException(ex);
    }

    void Complete()
    {
        Debug.LogFormat("Complete");
    }

}

代碼解析

Where指定返回一個bool值,true表示條件成立,執行之後的流,但不會依照就近原則,不會改變基礎流的包裝類型。


WhenAll

當流的所有子流全部完成以後,將數據同步到基礎流,一般用於多個網絡請求,UniRx特有

執行結果

在這裏插入圖片描述

代碼示例

public class No12_Mixed2 : MonoBehaviour
{ 
    void Start()
    {
        var unit  = Observable.ReturnUnit();

        var baidu = ObservableWWW.Get("http://www.baidu.com");
        var sina    = ObservableWWW.Get("http://www.sina.com");
        
        var whenAll = Observable.WhenAll(unit, baidu, sina);
        whenAll.Subscribe(Next, Error, Complete);
        
    }

    void Next(string[] arr)
    {
        Debug.LogFormat("whenAll網絡事件完成了,百度數據:{0} sina數據:{1}", arr[0].Substring(0, 10), arr[1].Substring(0, 10));
    }

    void Error(Exception ex)
    {
        Debug.LogException(ex);
    }

    void Complete()
    {
        Debug.LogFormat("Complete");
    }

}

代碼解析

WhenAll第一傳入的是Unit的流,需要一個Unit從充當,擁有內部邏輯,使用ReturnUnit返回一個Unit基礎流,之後可以傳入一個或者多個參數列表,包裝類型必須一致。


Never<>()

創建一個基礎流,既不完成,也不終止,圖解

在這裏插入圖片描述

執行結果

代碼示例

var never = Observable.Never<string>();

代碼解析

Never一般用於佔位,等待以後有功能的時候來替補位置。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章