neuecc / UniRx

Reactive Extensions for Unity
MIT License
7.1k stars 889 forks source link

Strange behavior when using WithLatestFrom on reactive properties #482

Closed david-hindman closed 2 years ago

david-hindman commented 3 years ago

Example:

void Start()
{
    A = new ReactiveProperty<int>(1);
    B = new ReactiveProperty<int>(2);

    Debug.Log(A.Value);
    Debug.Log(B.Value);

    A.WithLatestFrom(B, (a, b) => (a, b))
        .Subscribe(ab => Debug.Log(ab.a + ab.b));
}

Expected output: 1 2 3

Actual output: 1 2

Strangely, if I add a DelayFrame operator on A as seen below, the expected output is produced:

void Start()
{
    A = new ReactiveProperty<int>(1);
    B = new ReactiveProperty<int>(2);

    Debug.Log(A.Value);
    Debug.Log(B.Value);

    A.DelayFrame(1).WithLatestFrom(B, (a, b) => (a, b))
        .Subscribe(ab => Debug.Log(ab.a + ab.b));
}

I'm sure this can be explained but I don't understand it and it's certainly not intuitive. Is this an issue or am I misunderstanding something about how WithLatestFrom works?

FodderMK commented 3 years ago

Based on the marble diagram it looks like this is how WithLatestFrom is supposed to work: https://rxjs-dev.firebaseapp.com/api/operators/withLatestFrom

You don't get a value on subscription, you get it after you have subscribed and the left value (A) emits. The reason your second example works is because the left value is emitting 1 frame after the subscription.