UniRxのZip, ZipLatest, CombineLatestの挙動の比較
ZipLatestについての日本語の情報が見つからなかったので書きます。
2016年2月のコミットくらいで追加されていました。 github.com
ソースコード
using UnityEngine; using UniRx; using System.Linq; public class ZipLatest_test : MonoBehaviour { Subject<string> A = new Subject<string> (); Subject<string> B = new Subject<string> (); void Start () { Observable.Zip (A, B) .Select (_ => _ [0] + ", " + _ [1]) .Subscribe (_ => Debug.Log ("Zip: " + _)); Observable.ZipLatest (A, B) .Select (_ => _ [0] + ", " + _ [1]) .Subscribe (_ => Debug.Log ("ZipLatest: " + _)); Observable.CombineLatest (A, B) .Select (_ => _ [0] + ", " + _ [1]) .Subscribe (_ => Debug.Log ("CombineLatest: " + _)); A.OnNext ("A0"); A.OnNext ("A1"); B.OnNext ("B2"); A.OnNext ("A3"); B.OnNext ("B4"); B.OnNext ("B5"); } }
結果
Zip
Zip: A0, B2 Zip: A1, B4 Zip: A3, B5
それぞれのストリームに送られてきたメッセージを保持し、1つずつ揃ったタイミングで流れます。
ZipLatest
ZipLatest: A1, B2 ZipLatest: A3, B4
それぞれのストリームに送られてきた最新のメッセージを保持し、2つ揃ったタイミングで流れます。
CombineLatest
CombineLatest: A1, B2 CombineLatest: A3, B2 CombineLatest: A3, B4 CombineLatest: A3, B5
それぞれの最新のメッセージを保持し、いずれかのストリームにメッセージが流れてきたタイミングで流れます。
Zip, ZipLatestと違い、最新の値は一度流れても保持され続けます。
参考
時系列順の表
内部の実装まで見てないので、集合表現とかはイメージです。
時系列 | t0 | t1 | t2 | t3 | t4 | t5 | t6 |
---|---|---|---|---|---|---|---|
Aに流れるメッセージ | A0 | A1 | - | A3 | - | - | - |
Bに流れるメッセージ | - | - | B2 | - | B4 | B5 | - |
Zip - A | (A0) | (A0,A1) | (A0,A1) | (A1,A3) | (A1,A3) | (A3) | () |
Zip - B | () | () | (B2) | () | (B4) | (B5) | () |
Zipの出力 | - | - | A0, B2 | - | A1, B4 | A3, B5 | - |
ZipLatest - A | (A0) | (A1) | (A1) | (A3) | (A3) | () | () |
ZipLatest - B | - | - | (B2) | () | (B4) | (B5) | () |
ZipLatestの出力 | - | - | A1, B2 | - | A3, B4 | - | - |
CombineLatest - A | (A0) | (A1) | (A1) | (A3) | (A3) | (A3) | (A3) |
CombineLatest - B | - | - | (B2) | (B2) | (B4) | (B5) | (B5) |
CombineLatestの出力 | - | - | A1, B2 | A3, B2 | A3, B4 | A3, B5 | - |
それぞれのA,Bが揃ったタイミングで後続に流れるイメージです。
補足ですが、CombineLatestのt6に関しては、値は保持されていますがメッセージが流れてきていないため、発火していません。
追記(7/4)
以下の記事に送っていたZipLatestの追加の編集リクエストが通ったので、よければそちらも参考にしてみてください。