Sample()
Scan()
Switch()
ToAwaitableEnumerator()
Wait()
WithLatestFrom()
Materialize()
Dematerialize()
Multicast()
Sample/SampleFrame
對一個基礎流進行採樣,採樣的數據以基礎流最近輸出的一個數據爲準,圖解
第一條線是基礎流在輸出數據
第二條線是一個Sample的流在進行採樣
A採樣輸出1,他最近可取的數據爲1;B同理,C採樣不到數據,因爲C最近的數據已經被Sample了;
爲什麼C採樣不到3,因爲3沒有被輸出,C不知道有3的存在
結束採樣輸出了5,因爲採樣結束,基礎流在輸出,所以輸出了5
執行結果
代碼示例
public class No17_Mixed7 : MonoBehaviour
{
void Start()
{
var sample = Observable.EveryUpdate().Sample(TimeSpan.FromMilliseconds(200));
sample.Subscribe(Next, Error, Complete);
}
void Next(long frame)
{
Debug.LogFormat("Sample的幀:{0}", frame);
}
void Error(Exception ex)
{
Debug.LogException(ex);
}
void Complete()
{
Debug.LogFormat("Complete");
}
}
代碼解析
Scan
對流發出的數據進行掃描,將處理的結果返回到輸出,操作和內聚差不多,圖解
執行結果
代碼示例
public class No17_Mixed7 : MonoBehaviour
{
void Start()
{
var scan = Observable.Range(1, 3).Scan(ScanMethod);
scan.Subscribe(Next, Error, Complete);
}
// origin 1 2 3
// result 1 3 6
private int ScanMethod(int pre, int next)
{
return pre + next;
}
void Next(int result)
{
Debug.LogFormat("Scan之後的結果:{0}", result);
}
void Error(Exception ex)
{
Debug.LogException(ex);
}
void Complete()
{
Debug.LogFormat("Complete");
}
}
代碼解析
Range輸出的值是123,經過Scan之後是136,第一個Scan的pre值爲0
Switch
將多個獨立輸出流的輸出數據彙總到一個流裏面,圖解
第一條橫線是一個匯聚多個流的基礎流,在輸出數據,它由兩個流組成,輸出的數據分佈是圓形和三角形;
基礎流通過Switch之後,把所有的分支流全部彙總到一個流上輸出
結束以最後一個流的結束標誌位基準
執行結果
代碼示例
public class No17_Mixed7 : MonoBehaviour
{
void Start()
{
var subject = new Subject<IObservable<int>>();
var sources = subject.AsObservable();
var @switch = Observable.Switch(sources);
subject.Subscribe(Next);
@switch.Subscribe(NextSwitch, ErrorSwitch, CompleteSwitch);
subject.OnNext(Observable.Return(10));
subject.OnNext(Observable.Return(30));
subject.OnCompleted();
}
void Next(IObservable<int> observable)
{
observable.Subscribe(
v => Debug.LogFormat("Next Sources:{0}", v),
()=> Debug.LogFormat("Next Complete"));
}
void NextSwitch(int value)
{
Debug.LogFormat("NextSwitch Sources:{0}", value);
}
void ErrorSwitch(Exception ex)
{
Debug.LogException(ex);
}
void CompleteSwitch()
{
Debug.LogFormat("NextSwitch Complete");
}
}
代碼解析
自定義了一個主題,主題的包裝類型是一個流;AsObservable把主題當成一個流來處理,理論上來說主題每次Next一個流,讓流獨自去運作;每個流都會執行完整的,使用Switch之後,把主題包裝的集合流全部映射到一個流上,只有一個Complete執行,是我們手動調用的Complete方法。
ToAwaitableEnumerator
UniRx特有,將一個流轉換成一個可等待的協同,等待流的執行結果,有結果或錯誤信息
執行結果
代碼示例
public class No17_Mixed7 : MonoBehaviour
{
void Start()
{
var subject = new Subject<int>();
var enumerator = subject.ToAwaitableEnumerator(Result, Error);
StartCoroutine(enumerator);
var disposable = subject.Subscribe(Next, Error, Complete);
subject.OnNext(10);
subject.OnNext(30);
subject.OnCompleted();
disposable.AddTo(gameObject);
}
void Result(int value)
{
Debug.LogFormat("ToAwaitableEnumerator:{0}", value);
}
void Next(int next)
{
Debug.LogFormat("Subject Next:{0}", next);
}
void Error(Exception ex)
{
Debug.LogException(ex);
}
void Complete()
{
Debug.LogFormat("Complete");
}
}
代碼解析
Wait
UniRx特有,封裝線程之間通訊的操作,具體用法未知
執行結果
代碼示例
public class No17_Mixed7 : MonoBehaviour
{
void Start()
{
var subject = new Subject<int>();
subject.Subscribe(Next, Error, Complete);
subject.OnNext(10);
var wait = subject.Wait(TimeSpan.FromMilliseconds(1000));
Debug.LogFormat("Wait:{0}", wait);
subject.OnNext(30);
subject.OnCompleted();
}
void Next(int next)
{
Debug.LogFormat("Subject Next:{0}", next);
}
void Error(Exception ex)
{
Debug.LogException(ex);
}
void Complete()
{
Debug.LogFormat("Complete");
}
}
代碼解析
WithLastestFrom
UniRx特有,操作兩個流,left和right,取右邊流最終的執行結果給left操作返回
執行結果
代碼示例
public class No17_Mixed7 : MonoBehaviour
{
void Start()
{
var subject0 = new Subject<int>();
var subject1 = new Subject<int>();
var latest = subject0.WithLatestFrom(subject1, Selector);
latest.Subscribe(Next, Error, Complete);
subject0.OnNext(11);
subject1.OnNext(22);
subject1.OnNext(33);
subject0.OnNext(44);
subject0.OnNext(55);
}
private int Selector(int left, int right)
{
return left + right;
}
void Next(int next)
{
Debug.LogFormat("WithLatestFrom Next:{0}", next);
}
void Error(Exception ex)
{
Debug.LogException(ex);
}
void Complete()
{
Debug.LogFormat("Complete");
}
}
代碼解析
通過WithLatestFrom,以右邊的流Subject1爲準,取Subject1流最後輸出的數據,當以後有數據執行的時候(Left)執行
Selector操作,取一個流最後的值,附加到另外一個操作流上返回執行結果。
Materialize
使得完整的流通過Materialize之後變成了單步執行,擁有全部的執行過程,圖解
執行結果
代碼示例
public class No17_Mixed7 : MonoBehaviour
{
void Start()
{
var materialize = Observable.Range(1, 3).Materialize();
materialize.Subscribe(Next, Error, Complete);
}
void Next(Notification<int> notification)
{
Debug.LogFormat("Materialize Next:{0}", notification);
}
void Error(Exception ex)
{
Debug.LogException(ex);
}
void Complete()
{
Debug.LogFormat("Complete");
}
}
代碼解析
Dematerialize
和Materialize是功能相反的一對,將Materialize的單步劃分合併成一個完整的流,圖解
執行結果
public class No17_Mixed7 : MonoBehaviour
{
void Start()
{
var materialize = Observable.Range(1, 3).Materialize().Dematerialize();
materialize.Subscribe(Next, Error, Complete);
}
void Next(int value)
{
Debug.LogFormat("Dematerialize Next:{0}", value);
}
void Error(Exception ex)
{
Debug.LogException(ex);
}
void Complete()
{
Debug.LogFormat("Complete");
}
}
代碼解析
Multicast
功能和Pulish差不多,將流變成Connectable的流,再處理流的數據,可以指定一個Subject來同步輸出,圖解
執行結果
代碼示例
public class No17_Mixed7 : MonoBehaviour
{
void Start()
{
var subject = new Subject<int>();
subject.Subscribe(
value => Debug.LogFormat("Subject Next:{0}", value),
() => Debug.LogFormat("Subject Complete"));
var multicast = Observable.Range(1, 3).Multicast(subject).RefCount();
multicast.Subscribe(Next, Error, Complete);
}
void Next(int value)
{
Debug.LogFormat("Multicast Next:{0}", value);
}
void Error(Exception ex)
{
Debug.LogException(ex);
}
void Complete()
{
Debug.LogFormat("Multicast Complete");
}
}
代碼解析
總結
UniRx全部字段文檔已完結,之後補充UniRx專題相關的知識;UniRx必定是以後流行必備的一門編程語言技術,高度的靈活性,對功能的便捷和自由拓展能力,好比《我的世界》遊戲一般;使用了C#優美的異步,能夠讓使用者無論從畫質還是邏輯都能上升一個臺階。