Angular 如何等待外部可观察对象发出一个值,然后在订阅另一个可观察对象之前检查条件?

Angular 如何等待外部可观察对象发出一个值,然后在订阅另一个可观察对象之前检查条件?,angular,rxjs,Angular,Rxjs,first$可能会在整个应用程序生命周期(角度)中继续发出多个值。如何确保第二个$订阅后不会再次订阅?您可以先筛选,然后再订阅一个: const subscription: Subscription; const first$ // Observable A const second$ // Observable B // When `first$` emits, I am checking the value and // subscribe to `second$` i

first$
可能会在整个应用程序生命周期(角度)中继续发出多个值。如何确保第二个$订阅后不会再次订阅?

您可以先筛选,然后再订阅一个:

const subscription: Subscription;
const first$      // Observable A
const second$     // Observable B

// When `first$` emits, I am checking the value and 
// subscribe to `second$` if value is more than 5
subscription.add(
   first$.subscribe(value => {
      if(value > 5) {
          subscription.add(
             second$.subscribe((name) => console.log(name))
          );
       }
   });
);
尝试切换地图:

first$.pipe(filter(v => v > 5), first()).subscribe(() => second$.subscribe((name) => console.log(name)))
开关图:

this.second$ = this.first$.pipe(
  filter(v => v > 5),
  // take(1), // if necessary
  switchMap(v => this.doSomethingAsyncWith()),
);
switchMap
将自动取消订阅内部可观察对象,以防外部可观察对象发出新值


在订阅回调中调用subscribe通常是一种不好的做法。是处理这种情况的最好方法。可以使用随跳过,直到值大于5,然后订阅管道

从'rxjs/operators'导入{filter,skipUntil};
//...
第二根管子(
skipUntil(第一个$.pipe(过滤器(值=>值>5)),
).subscribe((名称)=>console.log(名称))

您可能希望查看rxjs switchMap,因为@MoxxiManagarm提到的过滤器也很好:
first$.pipe(点击(resultFirst=>console.log('resultFirst',resultFirst))、过滤器(v=>v>5)、switchMap(()=>$second)、点击(resultSecond=>console.log('resultSecond',resultSecond)),订阅()
    import { BehaviorSubject, EMPTY, interval } from 'rxjs';
    import { map, switchMap, tap } from 'rxjs/operators';

    const first$ = interval(1000).pipe(
        map(() => Math.random() * 10)
    );

    const $second = new BehaviorSubject('second obs');

    first$.pipe(
        tap(resultFirst => console.log('resultFirst', resultFirst)),
        // conditionally subscribe to $second
        switchMap(resultFirst => resultFirst > 5 ? $second : EMPTY),
        tap(resultSecond => console.log('resultSecond', resultSecond)),
    ).subscribe();