【问题标题】:is there a Better way rather than to chain subscribe inside a subscribe with an if condition有没有更好的方法,而不是在带有 if 条件的订阅中链接订阅
【发布时间】:2021-08-01 00:14:46
【问题描述】:

有没有更好的方法来重写此代码并避免链接订阅?

我为什么要链接?因为我需要在子订阅中输出source1$ 而且我还有if 条件,因为我想有条件地调用子订阅

PS 我在post 中检查了解决方案

这是stackblitz link 和代码

    import { from } from 'rxjs';

//emit array as a sequence of values
const source1$ = from([1]);
const source2$ = from([2]);
const source3$ = from([3]);

const useCond1 = true; // this is dynamic can be false too
const useCond2 = true; // this is dynamic can be false too

source1$.subscribe(val => {
  if (useCond1) {
    source2$.subscribe(() => {
      console.log('val from source1 in source2', val);
    });
  }

  if (useCond2) {
    source3$.subscribe(() => {
      console.log('val from source1 in source3', val);
    });
  }
});

【问题讨论】:

    标签: rxjs


    【解决方案1】:

    不确定,但您似乎需要 switchMapmergeMapiif

    来自 rxjx 文档:

    import { fromEvent, iif, of } from 'rxjs';
    import { mergeMap, map, throttleTime, filter } from 'rxjs/operators';
    
    const r$ = of(`I'm saying R!!`);
    const x$ = of(`X's always win!!`);
    
    fromEvent(document, 'mousemove')
      .pipe(
        throttleTime(50),
        filter((move: MouseEvent) => move.clientY < 210),
        map((move: MouseEvent) => move.clientY),
        mergeMap(yCoord => iif(() => yCoord < 110, r$, x$))
      )
      .subscribe(console.log);
    

    【讨论】:

      【解决方案2】:

      是的,有更好的方法!

      RxJS 提供了许多不同的运算符和静态函数来组合、过滤和转换可观察对象。当您使用库提供的内容时,您不需要嵌套订阅。

      一般来说,我发现在订阅中根本不执行任何逻辑会更简单,而是设计可发出所需数据的可观察对象。

      一个简单的例子可能如下所示:

      someValue$ = source1$.pipe(
        switchMap(val1 => useCond1 ? source2$ : of(val1))
      );
      
      someValue$.subscribe();
      

      switchMap 将在收到发射时订阅“内部可观察”。上面的逻辑说要么返回source1$ (val1) 发出的值,要么返回source2$ 发出的任何值,具体取决于useCond1 的值。

      所以source2$ 只有在useCond1 为真时才会被订阅;

      注意:switchMap 内部的函数应该返回一个 observable(因为 switchMap 订阅了它),所以 of 被用来将发出的值变成一个 observable。


      在您的情况下,假设您想要发出一些计算值,可能基于其他两个来源。

      我们可以使用combineLatest 来创建基于 3 个不同来源的单个 observable。由于您只想选择性地调用source2$source3$,我们可以根据您的条件定义源。然后我们可以使用map 将来自 3 个源的值数组转换为所需的输出:

      someValue$ = source1$.pipe(
        switchMap(val1 => {
          const s1$ = of(val1);
          const s2$ = useCond1 ? source2$ : of('default val2');
          const s3$ = useCond2 ? source3$ : of('default val3');
      
          return combineLatest([s1$, s2$, s3$]);
        }),
        map(([val1, val2, val3]) => {
          return ... // your logic to return desired value
        })
      );
      

      combineLatest 将发出一个数组,其中包含每个源的最新排放量,只要有任何源发出。这意味着someValue$ 将在任何来源发生变化时发出最新的计算值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-20
        • 1970-01-01
        • 2019-02-18
        • 2012-01-26
        • 1970-01-01
        • 2021-07-14
        相关资源
        最近更新 更多