Rxjs `distinctUntilChanged()` не работает

В потоке rxjs я использую distinctUntilChanged с isEqual lodash для фильтрации повторяющихся значений. Однако он похоже работает не так, как ожидалось. Возьмите следующий фрагмент кода

import { isEqual } from 'lodash-es';

let cachedValue: any;

function testFn(observableVal: Observable<any>) {
  return observableVal
    .pipe(
      distinctUntilChanged(isEqual),
      tap(val => {
        const equal = isEqual(cachedValue, val);
        console.log('"output":', equal, cachedValue, val);
        cachedValue = val;
      })
    )
}

В этом примере я ожидал бы, что const equal внутри функции tap никогда не будет === true. Я ожидаю, что distinctUntilChanged(isEqual) будет отфильтровывать любые значения, где isEqual(cachedValue, val) === true --> означает, что const equal === false всегда. Однако вывод консоли показывает:

"output": false undefined [ContactList]
"output": true [ContactList] [ContactList]
"output": true [ContactList] [ContactList]
"output": true [ContactList] [ContactList]

Я неправильно понимаю что-то фундаментальное в том, как работает оператор distinctUntilChanged()? Я опубликовал упрощенный пример, потому что фактический поток rxjs очень сложен, но я не ожидаю, что сложность будет иметь какое-либо значение, поскольку const equal всегда должно быть === false в операторе tap.

Я просто пытаюсь понять, что происходит, поэтому любая информация приветствуется. Спасибо!

Обновлять

Следует отметить, что если я изменю код на:

function testFn(observableVal: Observable<any>) {
  return observableVal
    .pipe(
      filter(val => {
        const equal = isEqual(cachedValue, val);
        cachedValue = val;
        return !equal;
      }),
      tap(val => {
        console.log('"output":', val);
      })
    )
}

Тогда фильтрация работает как положено. У меня сложилось впечатление, что distinctUntilChanged(isEqual) эквивалентно:

filter(val => {
  const equal = isEqual(cachedValue, val);
  cachedValue = val;
  return !equal;
})

Я ошибаюсь/не понимаю оператора distinctUntilChanged?


person John    schedule 24.02.2019    source источник


Ответы (1)


Я понял! Благодаря комментарию в проблеме rxjs: я случайно подписался на наблюдаться несколько раз (чего не должно было случиться). Несколько экземпляров console.log исходили из разных экземпляров подписки.

person John    schedule 24.02.2019
comment
Спасибо, что поддерживаете свой вопрос, Джон! Помогли мне понять, как написать собственный пользовательский оператор DistinctUntilChanged(). - person Valentine Bondar; 28.04.2020
comment
Это было полезно для меня, так как у меня была такая же проблема. Я забыл, что дважды подписался в своем шаблоне. Одна из ловушек полагаться на то, что tap должен делать то, что должен делать subscribe. - person MrMcPlad; 12.01.2021
comment
Полезно для меня. Я собираюсь посмотреть на слияние (), в которое я помещаю свой наблюдаемый объект DifferentUntilChanged. @Wilt, возможно, вам стоит просто подумать об удалении своего комментария, это бесполезно для другого, заканчивающегося здесь. - person RoboticRenaissance; 05.02.2021