Как работает CombineLatest реактивный оператор? - PullRequest
0 голосов
/ 22 января 2019

Я запустил следующий фрагмент кода внутри Linqpad:

$"[{(DateTime.Now.ToString("HH:mm:ss.fff"))}] 0 0".Dump();
Observable
    .Interval(TimeSpan.FromSeconds(3))
    .CombineLatest(Observable.Interval(TimeSpan.FromSeconds(10)), (x, y) => $"[{(DateTime.Now.ToString("HH:mm:ss.fff"))}] {x} {y}")
    .Do(Console.WriteLine).Wait();

Вот что я получил в результате:

[23:38:40.111] 0 0
[23:38:50.183] 2 0
[23:38:52.180] 3 0
[23:38:55.196] 4 0
[23:38:58.197] 5 0
[23:39:00.181] 5 1
[23:39:01.198] 6 1
[23:39:04.198] 7 1
[23:39:07.210] 8 1
[23:39:10.196] 8 2
[23:39:10.211] 9 2
[23:39:13.211] 10 2
[23:39:16.211] 11 2
[23:39:19.212] 12 2
[23:39:20.197] 12 3
[23:39:22.227] 13 3
[23:39:25.228] 14 3
[23:39:28.229] 15 3
[23:39:30.196] 15 4
[23:39:31.241] 16 4
[23:39:34.242] 17 4

Я не могу объяснить начало этой последовательности:

  1. Почему первое вычисленное значение 2 0?
  2. Почему 2 0 выводился через 10 секунд после запуска?

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Ничто не отправляется из CombineLatest, пока не будет получено хотя бы одно сообщение с каждой стороны.Это происходит через 10 секунд после старта в вашем случае, когда вы получаете первое сообщение из 10-секундной наблюдаемой: три сообщения из 3-секундной наблюдаемой вышли, так что третье излучается в паре с первым сообщением10 секунд.

0 голосов
/ 22 января 2019

От: http://reactivex.io/documentation/operators/combinelatest.html

CombineLatest

когда элемент испускается одной из двух наблюдаемых, объединяет последний элемент, испускаемый каждым наблюдаемым, через указанную функцию и испускает элементы на основе результатов этой функции

Возможно, этот модифицированный код поможет вам понять, что происходит:

$"[{(DateTime.Now.ToString("HH:mm:ss.fff"))}] 0 0".Dump();
Observable.Interval(TimeSpan.FromSeconds(3))
        .Do(x => $"[{(DateTime.Now.ToString("HH:mm:ss.fff"))}] {x} _".Dump())
    .CombineLatest(
        Observable.Interval(TimeSpan.FromSeconds(10))
            .Do(y => $"[{(DateTime.Now.ToString("HH:mm:ss.fff"))}] _ {y}".Dump()),
        (x, y) => $"[{(DateTime.Now.ToString("HH:mm:ss.fff"))}] {x} {y}")
    .Do(s => s.Dump())
    .Wait();
...