【问题标题】:Rxjs pipe function with multiple filter() and switchMap() operators in the chain链中具有多个 filter() 和 switchMap() 运算符的 Rxjs 管道函数
【发布时间】:2021-12-13 21:17:27
【问题描述】:

我正在重构一些写得很糟糕的旧 rxjs 代码,因此存在一些竞争条件。

所以我想根据各种条件使用一系列 filter() 运算符;但是我需要它来访问这条链上的每个过滤器运算符。即如果 Condition1 为真,则执行下一个 switchMap() - 否则只需执行下一个 filter()。对 Condition2..Condition4 应用相同的逻辑。

另外,我的 selectedNode 需要沿着链发出,因为 getChildNodes() 函数会获取额外的子节点并将它们推送到 selectedNode .

现在它只是在遇到第一个 FALSY 条件时退出 - 所以自然不会检查其余的过滤器。

如何使 if 在每个条件下都作为旧的 IF...THEN 语句执行?

这是我目前所拥有的:

    constructor(private readonly configSvc: ConfigService) {
        this.model$
            .pipe(
                filter((selectedNode) => !!selectedNode),

                // if condition1 passes, get child nodes of current node.
                filter((selectedNode) => myCondition1),
                switchMap((selNode) => this.getChildNodes(selNode, NodeType.Type1)),

                // if condition2 passes..
                filter((selectedNode) => myCondition2),
                switchMap((selNode) => this.getChildNodes(selNode, NodeType.Type2)),

                // if condition3 passes..
                filter((selectedNode) => myCondition3),
                switchMap((selNode) => this.getChildNodes(selNode, NodeType.Type3)),

                // if condition4 passes, get child nodes...
                filter((selectedNode) => myCondition4),
                switchMap((selNode) => this.getChildNodes(selNode, NodeType.Type4)),

                takeUntil(this.onDestroy),
            )
            .subscribe({
                next: (selectedNode: SelectedNode) => { // init the Network tree and notify listeners
                    this.initNetwork(selectedNode);
                    this.configNodesReadySource.next(selectedNode);
                },
            });
    }

或者也许订阅 mult observables,一个 alt 想法:

const condition1$ = this.model$.pipe(filter((node) => condition1), switchMap(...);
const condition2$ = this.model$.pipe(filter(...), switchMap(...);
const condition3$ = this.model$.pipe(filter(...), switchMap(...);
const condition4$ = this.model$.pipe(filter(...), switchMap(...);

forkJoin(...).subsribe(...); // join condition1 thru 4 to get final result ???

但是,我似乎有同样的问题或类似的问题。我从来没有达到订阅。

【问题讨论】:

  • 不确定您使用的是哪个版本的 RxJS,但我相信 iif 可以解决问题。
  • 6.6.3 和角度 13

标签: angular rxjs-pipeable-operators rxjs-filter


【解决方案1】:

您可以使用concatMap 来实现描述的级联

this.model$
.pipe(
    filter((selectedNode) => !!selectedNode),
    concatMap(selectedNode => myCondition1 ? this.getChildNodes(selectedNode, NodeType.Type1) : of(selectedNode)),
    concatMap(selectedNode => myCondition2 ? this.getChildNodes(selectedNode, NodeType.Type2) : of(selectedNode)),
    concatMap(selectedNode => myCondition3 ? this.getChildNodes(selectedNode, NodeType.Type3) : of(selectedNode)),
    concatMap(selectedNode => myCondition4 ? this.getChildNodes(selectedNode, NodeType.Type4) : of(selectedNode)),
    takeUntil(this.onDestroy),
)
.subscribe({
    next: (selectedNode: SelectedNode) => { // init the Network tree and notify listeners
        this.initNetwork(selectedNode);
        this.configNodesReadySource.next(selectedNode);
    },
});

【讨论】:

  • 但是我的 selectedNode 需要沿着链发出,因为 getChildNodes() 函数会获取额外的子节点并将它们推送到 selectedNode ,然后返回一个 Observable。
  • @bob.mazzo 请检查我的新编辑
  • 好主意,这可能对我有用。但是我需要 of(selectedNode) 以便将其作为 Observable 发送给链中的下一个运算符。
  • 是的,这绝对是我的回答有误,应该改用of(selectedNode)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-28
  • 2017-10-12
  • 1970-01-01
相关资源
最近更新 更多