记一下UniRx的一系列操作符,以后忘记哪个或者哪个记不清楚了,方便回顾。
目录
1、Where
按条件进行筛选:
.Where(_ => Input.GetMouseButtonDown(1))
2、Select
挑选某个指定值
.Where(_ => Input.GetMouseButtonDown(1))
.Select(_ => "mouse down")
3、SelectMany
对序列进行获取,并创建新序列,可加入序列值或指定值
urls.SelectMany(url => "new:" + url);
4、First
只取触发事件的第一次
.First(_ => Input.GetMouseButtonDown(1))
5、Last
与First意义相反,只取触发事件的最后一次,在事件结束时起作用。
6、TakeLast
获取最后几项
7、Single
返回序列中单一特定的元素
urls.Single(url => url == 3);
8、Distinct
筛选不重复的结果
urls.Distinct()
.ToList()
.ForEach(url => Debug.Log(url));
9、Concat
连接两个序列,从第一个尾部连接
urls1.Concat(urls2);
10、WhenAll
序列中所有条件都满足后执行
Observable.WhenAll(Observable.FromCoroutine(Coroutine1),Observable.FromCoroutine(Coroutine2));
11、OfType
根据知道类型筛选
urls.OfType<float>();
12、Cast
类型强制转换
urls.Cast<float>();
13、GroupBy
根据条件分组
urls.GroupBy(url => url.num);
14、Range
从某个数开始,后延生成几位
Observable.Range(6,3);
15、Take
从序列开头获取某几次
urls.Take(5);
16、Skip
跳过序列中指定数量的元素,之后返回剩余元素
Observable.EveryUpdate()
.Where(_=>Input.GetMouseButtonDown(0))
.Skip(5);
17、TakeWhile
如果指定条件为True,返回序列中的元素,否则跳过指定元素及后续元素。
Observable.EveryUpdate()
.Where(_=>Input.GetMouseButtonDown(0))
.TakeWhile((_,num) => !Input.GetMouseButtonUp(0) && num < 10);
18、SkipWhile
如果指定条件为True,跳过序列中的元素,否则返回后续元素。
Observable.EveryUpdate()
.Where(_=>Input.GetMouseButtonDown(0))
.SkipWhile((_,num) => !Input.GetMouseButtonUp(0) && num >10);
19、Zip
将指定函数应用于两个序列的对应元素,并生成新序列(Dictionary)
var leftStream = Observable.EveryUpdate().Where(_ => Input.GetMouseButtonDown(0));
var rightStream = Observable.EveryUpdate().Where(_ => Input.GetMouseButtonDown(1));
leftStream.Zip(rightStream, (left, right) => Unit.Default);
20、 Repeat
在序列中重复某个值
Observable.Repeat("Repeat 5 times", 5);
21、ToArray
创建数组
22、ToList
创建列表
23、Aggregate
序列累加器函数 ,从指定数值开始,返回指定函数结果值
urls.Aggregate((minurl, nexturl) => minurl < nexturl ? minurl : nexturl);
24、Empty
返回具体指定类型参数的空IEnumerable<T>
Observable.Empty<string>()
.Subscribe(_ => Debug.Log("Next"), _ => Debug.Log("OnCompleted"));
25、Interval
间隔一段时间执行
Observable.Interval(TimeSpan.FromSeconds(1f))
.Subscribe(times => Debug.Log(times));
26、TakeUntil
当第二个Observable发射一项数据或停止时,丢弃原始Observable发射的任何数据
Observable.EveryUpdate()
.TakeUntil(Observable.EveryUpdate().Where(mouse => Input.GetMouseButtonDown(0)))
.Subscribe(_ => Debug.Log("No Mouse Down"));
27、SkipUntil
丢弃原始Observable发射的数据,直到第二个Observable发射一项
Observable.EveryUpdate()
.SkipUntil(Observable.EveryUpdate().Where(mouse => Input.GetMouseButtonDown(0)))
.Take(100)
.Repeat()
.Subscribe(_ => Debug.Log("Mouse Down"));
28、BatchFrame
在几帧内将数据合并
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.BatchFrame(100, FrameCountType.EndOfFrame)
.Subscribe(clicks => Debug.Log(clicks.Count));
29、Buffer
缓冲
Observable.Interval(TimeSpan.FromSeconds(1f))
.Buffer(TimeSpan.FromSeconds(3f))
.Subscribe(listCount => { Debug.Log("listCount:" + listCount);
listCount.ToList()
.ForEach(list => Debug.Log("list:" + list));
}) ;
30、Throttle
节流阀,截取信息,延后释放
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.Throttle(TimeSpan.FromSeconds(1f))
.Subscribe(_ => Debug.Log("Mouse Down"));
31、Delay
延迟一段时间,再发射Observable的数据
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.Delay(TimeSpan.FromSeconds(1f))
.Subscribe(_ => Debug.Log("Mouse Down"));
32、SampleFrame
帧采样
Observable.EveryUpdate()
.SampleFrame(5)
.Subscribe(frame => Debug.Log(frame));
33、return
返回
Observable.Return(Unit.Default)
.Delay(TimeSpan.FromSeconds(1f))
.Repeat()
.Subscribe(_ => Debug.Log("after 1 seconds"));
34、Timer
在一个给定延迟后,发射一个给定的值
Observable.Timer(TimeSpan.FromSeconds(1f), TimeSpan.FromSeconds(0.5f))
.Subscribe(_ => Debug.Log("after 1 seconds"));
35、Sample
定期发射Observable最近发射的数据
int clickCount = 0;
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.Select(_ => clickCount++)
.Sample(TimeSpan.FromSeconds(3f))
.Subscribe(_ => Debug.LogFormat("This is {0} times", clickCount));
36、TimeStamp
给Observable发射的数据附加一个时间戳
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.Timestamp()
.Subscribe(timestamp => Debug.LogFormat("Now time is: {0} ", timestamp.Timestamp));
37、ThrottleFirst
在一段时间内,节流第一次输出
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.ThrottleFirst(TimeSpan.FromSeconds(3f))
.Subscribe(_ => Debug.Log("Mouse Down"));
38、TimeInterva
将一个发射数据的Observable转换为发射那些数据的发射时间间隔的Observable
(返回时间间隔,设定值)
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.Select(_=> "clicked")
.TimeInterval()
.Subscribe(timeInterval => Debug.LogFormat("TimeInterval:{0},TimeValue:{1}",timeInterval.Interval,timeInterval.Value));
39、Defer
推迟,直到有观察者订阅时才创建Observable,为每个观察者创建新的Observable
40、Never
创建一个不终止也不发射数据的Observable
41、Scan
连续地对数据序列的每一项应用一个函数,然后连续发射结果。
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.Scan(0, (times, nextValue) => ++times)
.Subscribe(times => Debug.Log(times));
42、Switch
将一个发射 多个Observable 的 Observable 转换成另一个 单独的Observable,后者发射那些Observable最近发射的数据项
(状态切换)
var buttonDownStream = Observable.EveryUpdate().Where(_ => Input.GetMouseButtonDown(0));
var buttonUpStream = Observable.EveryUpdate().Where(_ => Input.GetMouseButtonUp(0));
buttonDownStream.Select(_ =>
{
Debug.Log("Mouse Down");
return buttonUpStream;
})
.Switch()
.Subscribe(_ => Debug.Log("Mouse Up"));
43、StartWith
在一个Observable的前面添加一个数据序列
Observable.Return("Start Event")
.StartWith("Before Add")
.Aggregate((current, next) => current + next)
.Subscribe(Debug.Log);
44、CombineLatest
当两个Observable中的任何一个发射了数据时,使用一个函数结合每个Observable 发射的最近数据项,并且基于这个函数的结果发射数据。
int down = 0;
int up = 0;
var buttonDownStream = Observable.EveryUpdate().Where(_ => Input.GetMouseButtonDown(0)).Select(_ => (++down).ToString());
var buttonUpStream = Observable.EveryUpdate().Where(_ => Input.GetMouseButtonUp(0)).Select(_ => (++up).ToString());
buttonDownStream.CombineLatest(buttonUpStream, (right, left) => right + left)
.Subscribe(Debug.Log);
45、Do
注册一个动作作为原始Observable生命周期的一个占位符
46、Merge
合并Observable
47、Materialize/DeMaterialize
将数据项和事件通知都当作数据发射
var subject = new Subject<int>();
var onlyException = subject.Materialize()
.Where(n => n.Exception != null)
.Dematerialize();
subject.Subscribe(i => Debug.LogFormat("subject Subscribe: {0}", i), ex => Debug.LogFormat("subject Exception:{0}", ex));
onlyException.Subscribe(i => Debug.LogFormat("Subscribe: {0}", i), ex => Debug.LogFormat("Exception:{0}", ex));
subject.OnNext(555);
subject.OnError(new Exception());
输出结果:因为Exception为null,故onlyException不发送555
48、IgnoreElements
不发射任何数据,只发射Observable的终止通知
var subject = new Subject<int>();
var ignore = subject.IgnoreElements();
subject.Subscribe(i => Debug.LogFormat("subject : {0}", i), () => Debug.Log("subject OnCompleted"));
ignore.Subscribe(i => Debug.LogFormat("ignore: {0}", i), () => Debug.Log("ignore OnCompleted"));
subject.OnNext(1);
subject.OnCompleted();
输出结果:ignore不输出数据
49、DistinctUntilChanged
监听重复数据,并将数据剔除
string state = "Idel";
Observable.EveryUpdate()
.DistinctUntilChanged(_ => state)
.Subscribe(_ => Debug.Log("State is changed to:" + state));
Observable.ReturnUnit()
.Delay(TimeSpan.FromSeconds(1f))
.Do(_ => state = "Jump")
.Delay(TimeSpan.FromSeconds(1f))
.Do(_ => state = "Jump")
.Delay(TimeSpan.FromSeconds(1f))
.Do(_ => state = "Run")
.Subscribe();
输出结果:跳过Jump
50、 Create
使用一个函数,从头创建一个Observable
Observable.Create<int>(observable =>
{
observable.OnNext(1);
observable.OnNext(2);
Observable.Timer(TimeSpan.FromSeconds(1f))
.Subscribe(_ => observable.OnCompleted());
return Disposable.Create(() => Debug.Log("Observers have been destroyed!"));
})
.Subscribe(num => Debug.Log("Observable:" + num));
51、Amb
给定两个或多个Observable,它只发射最先发射数据或通知的 那个Observable 的所有数据
Observable.Amb(
Observable.Timer(TimeSpan.FromSeconds(1f)).Select(_ => "1 sec"),
Observable.Timer(TimeSpan.FromSeconds(2f)).Select(_ => "2 sec"),
Observable.Timer(TimeSpan.FromSeconds(3f)).Select(_ => "3 sec"))
.Subscribe(str => Debug.Log(str));
52、TimeOut
对原始的Observable的镜像,如果过了指定时长仍没有发射数据,会发送错误通知
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.Timeout(TimeSpan.FromSeconds(3f))
.Subscribe(_ => Debug.Log("Mouse Down"));
53、FromEvent
将其他种类的对象和数据类型转换为Observable
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.Subscribe(_ => mouseDownEvent.Invoke());
Observable.FromEvent(mouseEvent => mouseDownEvent += mouseEvent, mouseEvent => mouseDownEvent -= mouseDownEvent)
.First()
.Subscribe(_ =>Debug.Log("Clicked!"));
54、Publish
将普通的Observable转换为可连接的Observable
var unShared = Observable.Range(1, 3);
unShared.Subscribe(num => Debug.Log("first : " + num));
unShared.Subscribe(num => Debug.Log("second : " + num));
var shared = unShared.Publish();
shared.Subscribe(num => Debug.Log("first : " + num));
shared.Subscribe(num => Debug.Log("second : " + num));
Observable.Timer(TimeSpan.FromSeconds(1f))
.Subscribe(_ => shared.Connect());
输出结果:注意shared输出结果并行
55、RefCount
让一个可连接的Observable,行为像一个普通的Observable
IEnumerator PublishStart()
{
var observablePublish = Observable.Interval(TimeSpan.FromSeconds(1f))
.Do(n => Debug.Log("Publish : " + n))
.Publish()
.RefCount();
var observableAction1 = observablePublish.Subscribe(_ => Debug.Log("#####"));
var observableAction2 = observablePublish.Subscribe(_ => Debug.Log("?????"));
yield return new WaitForSeconds(3f);
observableAction1.Dispose();
yield return new WaitForSeconds(3f);
observableAction2.Dispose();
}
输出结果:当一个订阅结束后,另一个仍在执行
56、Replay
保证所有观察者收到相同的数据,即使他们在Observable开始发射数据后才订阅
var observableReplay = Observable.Interval(TimeSpan.FromSeconds(1f))
.Do(n => Debug.Log("Replay : " + n))
.Replay();
observableReplay.Subscribe(l => Debug.Log("#####"));
observableReplay.Connect();
Observable.Timer(TimeSpan.FromSeconds(3f))
.Subscribe(_ =>
{
observableReplay.Subscribe(l => Debug.Log("?????"));
});
输出结果:在另一个观察者订阅后,之前未获取的数据统一发送
57、Connect
让一个可连接的Observable开始发射数据给订阅者
58、Throw
创建一个不发射数据,并以错误终止的Observable
Observable.Throw<String>(new Exception("Error!"))
.Subscribe(_ => Debug.Log("No Debug"), ex => Debug.Log(ex));
59、Catch
从OnError通知中恢复发射数据
Observable.Throw<String>(new Exception("Error!"))
.Catch<String, Exception>(e =>
{
Debug.Log(e.Message);
return Observable.Timer(TimeSpan.FromSeconds(1f))
.Select(_ => "Catch success!");
})
.Subscribe(Debug.Log);
60、Finally
注册一个动作,当它产生的Observable终止之后会被调用,无论是正常或是异常终止
var subject = new Subject<int>();
var subjectFinally = subject.Finally(() => Debug.Log("Finally Run!"));
subjectFinally.Subscribe(n => Debug.Log(n), () => Debug.Log("OnCompleted!"));
subject.OnNext(1);
subject.OnNext(2);
subject.OnCompleted();
61、DelaySubscription
延迟订阅
Debug.Log(Time.time);
Observable.ReturnUnit()
.DelaySubscription(TimeSpan.FromSeconds(1f))
.Subscribe(_ => Debug.Log(Time.time));
62、PairWise
Observable.Range(0, 5)
.Pairwise()
.Subscribe(pair => Debug.Log("Previous: " + pair.Previous + " " + "Current: " + pair.Current));
63、NextFrame
延一帧执行
Observable.NextFrame()
.Subscribe(_ => Debug.Log("NextFrame!"));
64、DelayFrame
延帧执行
Observable.ReturnUnit()
.Do(_ => Debug.Log(Time.frameCount))
.DelayFrame(10)
.Subscribe(_ => Debug.Log(Time.frameCount));
输出结果:DelayFrame顺延11帧
65、FrameInterval
帧数间隔
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.Timestamp()
.TimeInterval()
.FrameInterval()
.Subscribe(interval => Debug.LogFormat("frame interval:{0},time interva:{1}", interval.Interval, interval.Value.Value.Timestamp));
66、ForEachAsync
异步遍历序列
Observable.Range(0, 5)
.ForEachAsync(n => Debug.Log(n))
.Subscribe(l => Debug.Log(l));
输出结果:Subscribe无数据传入
67、FrameTimeInterva
帧总时间间隔
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.FrameTimeInterval()
.Subscribe(interval => Debug.LogFormat("frame time interval:{0},now frame:{1}", interval.Interval, interval.Value));
68、RepeatUntilDestroy
重复直到销毁
Observable.Timer(TimeSpan.FromSeconds(1f))
.RepeatUntilDestroy(this)
.Subscribe(_ => Debug.Log("Run!"));
69、OnserveOnMainThread
在主线程进行监听
Observable.Start(() => {
Thread.Sleep(TimeSpan.FromSeconds(1f));
return "Hello Thread!";
})
.ObserveOnMainThread()
.Subscribe(str => Debug.Log(str));
70、DelayFrameSubscript
延迟帧订阅
Debug.Log(Time.time);
Observable.ReturnUnit()
.DelayFrameSubscription(1000)
.Subscribe(_ => Debug.Log(Time.time));
71、ThrottleFirstFrame
节流帧数,在一段时间内,节流第一次输出
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.ThrottleFirstFrame(1000)
.Subscribe(_ => Debug.Log("Mouse Down"));
72、ThrottleFrame
节流帧数,屏蔽后续输入,并延迟输出
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.ThrottleFrame(1000)
.Subscribe(_ => Debug.Log("Mouse Down"));
73、TimeoutFrame
对原始的Observable的镜像,如果过了指定 帧数 仍没有发射数据,会发送错误通知
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.TimeoutFrame(1000)
.Subscribe(_ => Debug.Log("Mouse Down"));
74、TakeUntilDestroy
当指定物体被销毁时,丢弃原始Observable发射的任何数据
Observable.EveryUpdate()
.TakeUntilDestroy(this)
.Subscribe(_ => Debug.Log("No Destroy"));
75、TakeUntilDisable
当指定物体被禁用时,丢弃原始Observable发射的任何数据
Observable.EveryUpdate()
.TakeUntilDisable(this)
.Subscribe(_ => Debug.Log("No Disable"));
76、RepeatUntilDisabled
重复执行,直到指定物体被禁止
Observable.Timer(TimeSpan.FromSeconds(1f))
.RepeatUntilDisable(this)
.Subscribe(_ => Debug.Log("No Disable"));