【问题标题】:Rxjs `distinctUntilChanged()` appears to not be workingRxjs `distinctUntilChanged()` 似乎无法正常工作
【发布时间】:2019-02-24 21:18:01
【问题描述】:

在 rxjs 流中,我使用 distinctUntilChanged 和 lodash 的 isEqual 过滤掉重复值。但是它似乎没有按预期工作。取如下代码sn -p

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 equaltap 函数中永远不会=== 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 lodash rxjs-pipeable-operators


    【解决方案1】:

    我想通了!感谢rxjs issue 中的评论:我不小心多次订阅了 observable(这不应该发生)。多个console.log 实例来自不同的订阅实例。

    【讨论】:

    • 感谢约翰提出您的问题!帮助我了解如何编写自己的自定义 DistinctUntilChanged() 运算符
    • 这对我很有用,因为我遇到了同样的问题。我忘记了我在我的模板中订阅了两次。依赖tapsubscribe 应该做的事情的陷阱之一。
    • 对我有用。我将关注我将 distinctUntilChanged 可观察对象放入的 merge()。@Wilt 也许你应该考虑删除你的评论,这对其他人来说没有任何用处。
    • 如果其他人因同样的问题偶然发现此问题: distinctUntilChanged() 不适用于 FormControl 值更改:stackoverflow.com/questions/46889851/…
    【解决方案2】:

    如果有人会因为与我遇到的类似问题而来到这里 - 请记住,自定义比较器函数应返回 false 以传递 distinctUntilChanged 运算符。

    换句话说,当someProp 没有变化时,这个比较器将允许通过:

      distinctUntilChanged((prev, curr) => prev.someProp !== curr.someProp)
    

    而且这个 - 仅当 someProp 被更改时:

      distinctUntilChanged((prev, curr) => prev.someProp === curr.someProp)
    

    【讨论】:

      猜你喜欢
      • 2017-09-04
      • 2012-05-06
      • 2013-02-17
      • 2017-10-09
      • 2017-08-03
      • 2014-05-02
      • 2011-09-11
      • 2016-02-11
      • 1970-01-01
      相关资源
      最近更新 更多