Rxjs `distinctUntilChanged()` 似乎不起作用
Rxjs `distinctUntilChanged()` appears to not be working
在 rxjs 流中,我使用 distinctUntilChanged
和 lodash 的 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;
})
)
}
在这个例子中,我希望 tap
函数中的 const equal
永远不会 === 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);
})
)
}
然后筛选工作正常。 I was under the impression that distinctUntilChanged(isEqual)
was equivalent to:
filter(val => {
const equal = isEqual(cachedValue, val);
cachedValue = val;
return !equal;
})
我是否误会/误解了 distinctUntilChanged
运算符?
我想通了!感谢 rxjs issue 中的评论:我不小心多次订阅了 observable(这不应该发生)。多个 console.log
个实例来自不同的订阅实例。
万一有人因为我遇到的类似问题来到这里 - 请记住,自定义比较器函数应该 return false
以传递 distinctUntilChanged
运算符。
换句话说,当 someProp
:
没有变化时,这个比较器将允许通过
distinctUntilChanged((prev, curr) => prev.someProp !== curr.someProp)
并且这个 - 仅当 someProp
被更改时:
distinctUntilChanged((prev, curr) => prev.someProp === curr.someProp)
在 rxjs 流中,我使用 distinctUntilChanged
和 lodash 的 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;
})
)
}
在这个例子中,我希望 tap
函数中的 const equal
永远不会 === 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);
})
)
}
然后筛选工作正常。 I was under the impression that distinctUntilChanged(isEqual)
was equivalent to:
filter(val => {
const equal = isEqual(cachedValue, val);
cachedValue = val;
return !equal;
})
我是否误会/误解了 distinctUntilChanged
运算符?
我想通了!感谢 rxjs issue 中的评论:我不小心多次订阅了 observable(这不应该发生)。多个 console.log
个实例来自不同的订阅实例。
万一有人因为我遇到的类似问题来到这里 - 请记住,自定义比较器函数应该 return false
以传递 distinctUntilChanged
运算符。
换句话说,当 someProp
:
distinctUntilChanged((prev, curr) => prev.someProp !== curr.someProp)
并且这个 - 仅当 someProp
被更改时:
distinctUntilChanged((prev, curr) => prev.someProp === curr.someProp)