05.UniRx序列(Delay、DelayFrame、DelayFrameSubscription、DelaySubscription

Delay
DelayFrame
DelayFrameSubscription
DelaySubscription

Delay

延遲一定的時間來繼續執行之前的流,延遲的時間不計算在基礎流裏面,權當附加的一個功能,只針對基於時間的流有效果,圖解
在這裏插入圖片描述
輸出結果
在這裏插入圖片描述
代碼示例

public class No05_Delay : MonoBehaviour
{
    void Start()
    {
        var timerStream = Observable.Timer(TimeSpan.FromSeconds(3f));
        var timerSubscribe = timerStream.Subscribe(_ => Debug.Log("after 3 seconds"));
        var delayStream = timerStream.Delay(TimeSpan.FromSeconds(1f));
        var disposable = delayStream.Subscribe(Next, Error, Complete);

        disposable.AddTo(gameObject);
        timerSubscribe.AddTo(gameObject);
    }

    void Next(long time)
    {
        Debug.LogFormat("delay 1 second");
    }

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

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

代碼解析
代碼中訂閱了2次,每一個流都是獨立執行的,可以進行單獨的訂閱;只要流沒有執行Disposable,則流執行的內容一直保留,Delay只針對基於時間TimeSpan的基礎流有效果


DelayFrame

延遲一定的幀數繼續執行之前的流,延遲幀數不計算在基礎流裏面,圖解
在這裏插入圖片描述
執行結果
在這裏插入圖片描述

代碼示例

public class No05_Delay : MonoBehaviour
{
    void Start()
    {
        CompositeDisposable disposables = new CompositeDisposable();

        var updateStream = Observable.EveryUpdate();
        var mouseDownStream = updateStream.Where(_ => Input.GetMouseButtonDown((int) MouseButton.LeftMouse));
        var disposable = mouseDownStream.Subscribe(
            frame => Debug.LogFormat("點擊事件發生在{0}幀", frame), 
            ex => Debug.LogException(ex),
            () => Debug.LogFormat("Complete"));
        var delayFrameStream = mouseDownStream.DelayFrame(60);
        var disposable1 = delayFrameStream.Subscribe(Next, Error, Complete);

        disposables.Add(disposable);
        disposables.Add(disposable1);

        this.OnDestroyAsObservable().Subscribe(_ => disposables.Dispose());
    }

    void Next(long frame)
    {
        Debug.LogFormat("延遲事件發生在{0}幀", frame + 60);
    }

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

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

代碼解析
CompositeDisposable是內置提供的一個disposable集合工具類,在GameObject銷燬的時候調用集合的Dispose()來解除所有的數據方法綁定;使用this.OnDestroyAsObservable()可以將Destroy方法使用UniRx來管理,在Destroy的時候去釋放內存;Delay的功能有點類似於Pause,把基礎流給暫停了,延遲結束以後在繼續執行基礎流的數據。

DelayFrameSubscription

延遲一定幀數給訂閱者訂閱,圖解,同上

輸出結果
在這裏插入圖片描述
代碼示例

public class No05_Delay : MonoBehaviour
{
    void Start()
    {
        CompositeDisposable disposables = new CompositeDisposable();

        var updateStream = Observable.EveryUpdate();
        var mouseDownStream = updateStream.Where(_ => Input.GetMouseButtonDown((int) MouseButton.LeftMouse));
        var disposable = mouseDownStream.Subscribe(
            frame => Debug.LogFormat("點擊事件發生在{0}幀", frame), 
            ex => Debug.LogException(ex),
            () => Debug.LogFormat("Complete"));
        var delayFrameSubscriptionStream = mouseDownStream.DelayFrameSubscription(100);
        var disposable1 = delayFrameSubscriptionStream.Subscribe(Next, Error, Complete);

        disposables.Add(disposable);
        disposables.Add(disposable1);

        this.OnDestroyAsObservable().Subscribe(_ => disposables.Dispose());
    }

    void Next(long frame)
    {
        Debug.LogFormat("延遲訂閱事件發生在{0}幀", frame);
    }

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

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

代碼解析


DelaySubscription

同DelayFrameSubscription,但這個是基於時間來Delay處理

總結

基於時間單位在UniRx中表現分爲兩類,時間和幀,時間處理的基礎流需要使用時間的功能流來進行斜街;基於幀處理的基礎流需要使用幀的功能流來銜接。
UniRx中的執行的一個挨個一個的,但爲什麼上一個流沒有執行Complete方法呢,Rx內部機制決定的,當一個Observable執行OnNext方法的時候,會判定下一個Next是否爲空,不空則執行;所以中途訂閱的流不會執行Complete,只是一個執行結果的輸出;


如果你覺得對你有那麼一點幫助,請點贊打賞是給我最大的動力
呀哈哈,有能力的朋友可以掃下面的打賞二維碼↓↓↓
謝謝看官們↓↓↓
在這裏插入圖片描述

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