【Unity 随手记】UniRx操作符,入坑必背!!!

        记一下UniRx的一系列操作符,以后忘记哪个或者哪个记不清楚了,方便回顾。

目录

1、Where

2、Select

3、SelectMany

4、First

5、Last

6、TakeLast

7、Single

8、Distinct

9、Concat

10、WhenAll

11、OfType

12、Cast

13、GroupBy

14、Range

 15、Take

16、Skip

17、TakeWhile

18、SkipWhile

19、Zip

20、 Repeat

21、ToArray

22、ToList

23、Aggregate

24、Empty

25、Interval

26、TakeUntil

27、SkipUntil

28、BatchFrame

29、Buffer

30、Throttle

31、Delay

32、SampleFrame

33、return

34、Timer

35、Sample

36、TimeStamp

37、ThrottleFirst

38、TimeInterva

39、Defer

40、Never

41、Scan

42、Switch

43、StartWith

44、CombineLatest

45、Do

46、Merge

47、Materialize/DeMaterialize

48、IgnoreElements

 49、DistinctUntilChanged

 50、 Create

51、Amb

52、TimeOut

53、FromEvent

54、Publish

55、RefCount

 56、Replay

 57、Connect

58、Throw

59、Catch

 60、Finally

61、DelaySubscription

62、PairWise

63、NextFrame

64、DelayFrame

 65、FrameInterval

66、ForEachAsync

67、FrameTimeInterva

68、RepeatUntilDestroy

69、OnserveOnMainThread

70、DelayFrameSubscript

71、ThrottleFirstFrame

72、ThrottleFrame

73、TimeoutFrame

74、TakeUntilDestroy

75、TakeUntilDisable

76、RepeatUntilDisabled


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"));

猜你喜欢

转载自blog.csdn.net/qq_45360148/article/details/131479592