Rxjs `DifferentUntilChanged()`, кажется, не работает
В потоке rxjs я использую distinctUntilChanged
с Лодашем isEqual
отфильтровать повторяющиеся значения. Однако, похоже, что он работает не так, как ожидалось. Возьмите следующий фрагмент кода
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
оператор?
2 ответа
Я понял! Благодаря комментарию в выпуске rxjs: я случайно подписался на наблюдаемое несколько раз (чего не должно было быть). Кратный console.log
экземпляры приходили из разных экземпляров подписки.
В случае, если кто-то попадет сюда из-за проблемы, аналогичной моей, имейте в виду, что функция пользовательского компаратора должна возвращаться
false
пройти
distinctUntilChanged
оператор.
Другими словами, этот компаратор позволит пройти, когда нет изменений в:
distinctUntilChanged((prev, curr) => prev.someProp !== curr.someProp)
а это - только если
someProp
был изменен:
distinctUntilChanged((prev, curr) => prev.someProp === curr.someProp)