Javascript 我可以用另一个可观测对象的多个事件操纵一个可观测对象吗?

Javascript 我可以用另一个可观测对象的多个事件操纵一个可观测对象吗?,javascript,rxjs,Javascript,Rxjs,假设我有一组映射到输入字段的验证消息。假设我们从服务器获取这些验证消息 我还有一个映射到输入字段的变更事件流 每当我得到一个给定字段的更改事件时,我想 查看该字段是否有相应的验证消息 删除验证消息 这里有一个例子,希望能说明为什么通常的嫌疑犯(combineLatest,withLatestFrom)不能让我越界 combinelateest的问题是:第四个更改事件将过滤第二个验证数组 withLatestFrom的问题是:第三个更改事件将撤消第二个更改事件的工作 有人有什么建议吗?我找错树了

假设我有一组映射到输入字段的验证消息。假设我们从服务器获取这些验证消息

我还有一个映射到输入字段的变更事件流

每当我得到一个给定字段的更改事件时,我想

  • 查看该字段是否有相应的验证消息
  • 删除验证消息
  • 这里有一个例子,希望能说明为什么通常的嫌疑犯(combineLatest,withLatestFrom)不能让我越界

    combinelateest
    的问题是:第四个更改事件将过滤第二个验证数组

    withLatestFrom的问题是:第三个更改事件将撤消第二个更改事件的工作


    有人有什么建议吗?我找错树了吗?我把问题简化了吗?有没有一种RxJS方法适合这种情况

    每次收到验证消息时,似乎都在重新开始处理更改事件。在这种情况下,您可以尝试以下方法:

    filteredValidation$ = validation$.flatMapLatest(function ( aObjs ) {
      return changeEvent$.scan(function ( acc, changeEvent ) {
        return isIn(changeEvent, acc) ? removeChangeEvent(changeEvent, acc) : acc;
      }, aObjs);
    });
    
    isIn
    removeChangeEvent
    必须根据
    change\u事件的特定形状来编写,但这相当简单

    • 每个验证消息都将启动一个新流
    • 该流将具有一个状态,该状态由
      scan
      函数中的累加器
      acc
      表示,并且该状态本身是最新过滤的验证对象
    我还没有测试,但希望它能工作


    顺便说一句:我喜欢你的图表,它完美地说明了你想要实现的处理。

    每次你有一条验证消息,似乎你都在重新开始处理更改事件。在这种情况下,您可以尝试以下方法:

    filteredValidation$ = validation$.flatMapLatest(function ( aObjs ) {
      return changeEvent$.scan(function ( acc, changeEvent ) {
        return isIn(changeEvent, acc) ? removeChangeEvent(changeEvent, acc) : acc;
      }, aObjs);
    });
    
    isIn
    removeChangeEvent
    必须根据
    change\u事件的特定形状来编写,但这相当简单

    • 每个验证消息都将启动一个新流
    • 该流将具有一个状态,该状态由
      scan
      函数中的累加器
      acc
      表示,并且该状态本身是最新过滤的验证对象
    我还没有测试,但希望它能工作


    顺便说一句:我喜欢你的图表,它完美地说明了你想要实现的处理过程。

    这里是另一个不同技巧的答案。这个想法是类似的(使用
    scan
    来记住以前的值,但是我们通过一个减少函数生成当前值,该函数取决于发出值的源)

    jsfiddle:


    这里是另一个不同技巧的答案。这个想法是类似的(使用
    scan
    来记住以前的值,但是我们通过一个减少函数生成当前值,该函数取决于发出值的源)

    jsfiddle:


    我已经修改了上面的JSFIDLE,以展示我提出的解决方案

    jsfiddle:

    基本上,此版本使用
    Rx.Observable.window
    根据来自
    验证$
    流的新事件,将
    changeEvents$
    流分块

    var filteredValidation$ = validation$
        .merge(
            changeEvent$
            .window(validation$)
            .flatMapLatest(changeWindow => {
                return changeWindow.scan((acc, next) => acc.add(next), new Set());
            )
            .withLatestFrom(validation$, (filterSet, errs) => {
                return errs.filter(err => !filterSet.has(err.key));
            })
        )
        .distinctUntilChanged()
    

    我已经修改了上面的JSFIDLE,以展示我提出的解决方案

    jsfiddle:

    基本上,此版本使用
    Rx.Observable.window
    根据来自
    验证$
    流的新事件,将
    changeEvents$
    流分块

    var filteredValidation$ = validation$
        .merge(
            changeEvent$
            .window(validation$)
            .flatMapLatest(changeWindow => {
                return changeWindow.scan((acc, next) => acc.add(next), new Set());
            )
            .withLatestFrom(validation$, (filterSet, errs) => {
                return errs.filter(err => !filterSet.has(err.key));
            })
        )
        .distinctUntilChanged()
    

    很高兴你喜欢这个图表。此解决方案产生与CombineTest相同的场景,其中第四个更改事件将过滤第二个验证数组。很高兴您喜欢此图表。此解决方案产生与CombineTest相同的场景,其中第四个更改事件将过滤第二个验证数组。谢谢。这很有效。不过我有几个问题。这看起来像是对验证流进行了变异——这被认为是惯用的/良好的做法。我“感觉”不对,但我是Rx的新手,所以我知道什么?其次,我不确定在
    filteredValidations.merge(validations$.map(…)
    行中发生了什么。您将返回一个返回值的函数。你能解释一下你为什么这么做吗?第三个也是最不显著的点-以$..作为流的后缀。。。。我喜欢,但不能决定我是否会采用这个。这是常用的惯例吗。美元就够了:不记得我在哪里见过这个大会,但我一见钟情。我不会说它是常用的。毕竟,反应式编程还不是主流,所以惯例仍然可以接受。但是我更喜欢它而不是
    obsName
    ,或者
    nameObs
    ,而只是
    name
    。流突变:不,我没有对流进行突变。Rx中的流大部分是不可变的。但我确实将验证对象流转换为一个简化函数流。这些函数表示要对最新筛选的验证对象执行的操作。因此,他们获取最新的验证对象并返回一个新的验证对象。最新的验证对象作为
    scan
    函数中的
    prev
    参数提供。是的,用高阶函数进行推理有点困难,同意。先前使用
    flatMapLatest
    的解决方案确实更易于理解。谢谢。这很有效。不过我有几个问题。这看起来像是对验证流进行了变异——这被认为是惯用的/良好的做法。我“感觉”不对,但我是Rx的新手,所以我知道什么?其次,我不确定在
    filteredValidations.merge(validations$.map(…)
    行中发生了什么。您将返回一个返回值的函数。你能解释一下你为什么这么做吗?第三个也是最不显著的点-以$..作为流的后缀。。。。我喜欢,但不能决定我是否会采用这个。这是我们的共同愿望吗