確かによく考えるとそうなるかもしれないけれど、微妙に直感的ではなくて引っかかった挙動があったのでメモ。
簡単なコードから話を始めます。
var hoge = new ReactiveProperty<int>(0); hoge .Subscribe(x => { Debug.Log($"{Time.frameCount} Subscribe Start hoge = {x}"); hoge.Value = 3; Debug.Log($"{Time.frameCount} Subscribe End hoge = {x}"); }) .AddTo(this); await UniTask.DelayFrame(10); Debug.Log($"{Time.frameCount} Update hoge = 1"); hoge.Value = 1;
一瞬こんがらがりますが、実行結果が以下のようになるのは自明でしょう。
1 Subscribe Start hoge = 0 1 Subscribe End hoge = 0 11 Update hoge = 1 11 Subscribe Start hoge = 1 11 Subscribe Start hoge = 3 11 Subscribe End hoge = 3 11 Subscribe End hoge = 1
もちろん、最終的にhoge.Valueは3ですし、最後にSubscribeで渡ってくる値も3です。
続いて、DelayFrameを噛ませてみました。
hoge .DelayFrame(1) .Subscribe(x =>
ちょっとややこしくなってきましたが、まあこうなるのは分かるでしょう。
3 Subscribe Start hoge = 0 3 Subscribe End hoge = 0 5 Subscribe Start hoge = 3 5 Subscribe End hoge = 3 11 Update hoge = 1 12 Subscribe Start hoge = 1 12 Subscribe End hoge = 1 14 Subscribe Start hoge = 3 14 Subscribe End hoge = 3
さっきと変わらず、最終的にhoge.Valueは3ですし、最後にSubscribeで渡ってくる値も3です。
ここからが本題、さっきのDelayFrameをThrottleFrameに変えてみました。
hoge .ThrottleFrame(1) .Subscribe(x =>
この実行結果は
3 Subscribe Start hoge = 0 3 Subscribe End hoge = 0 11 Update hoge = 1 12 Subscribe Start hoge = 1 12 Subscribe End hoge = 1
になります。
最終的なhoge.Valueは3になりますが、Subscribeに3が渡ってくることはありません。
気持ちとしては13フレーム目で3が渡ってきて欲しいんですが、確かにOnNext中に値が変わったらThrottleに巻き込まれて握り潰されちゃうのかなーと思った挙動でした。