繁体   English   中英

RxJS switchMap 与 take 运算符

[英]RxJS switchMap with the take operator

我有一个返回以下 observable 的方法。

class Service {

  getData() {
     // the select observable will fire on every form change
     return this.store.select('filters').switchMap(filters => {
        return this.http.get('call the api with the filters')
     }).take(1);

  }
}

在我的组件中,我在提交时调用此方法。

class Component {

   submit() {
     this.service.getData().subscribe(...)
   }
}

问题是,在我调用一次提交后,我在第二次提交中看到两个 HTTP 调用。 我的问题是,在这种情况下,take(1) 运算符是否正在杀死内部外部可观察对象?

这与take()运算符完全无关。 您只需使用两条链对同一个源 Observable 进行两次订阅。

然后take(1)运算符只接受发出的第一个项目并发送complete通知。

现在你有以下内容:

           +-- switchMap --- take --> subscribe()
-- store --+
           +-- switchMap --- take --> subscribe()

因此,相同的值被推送到具有两个不同switchMap的两个不同链。

虽然你可能想要这样的东西:

                         +--> subscribe()
-- store --- switchMap --+
                         +--> subscribe()

例如你有这个(而不是do()你有switchMap() ):

const subject = new Subject();
const obs = subject
    .do(console.log);

obs.subscribe(i => console.log('next:', i));
obs.subscribe(i => console.log('next:', i));

subject.next(1);

...打印以下内容。 请注意, do()运算符接收到两个值:

1
next: 1
1
next: 1

相反,您可以使用:

const obs = subject
    .do(console.log)
    .publish()
    .refCount();

或这个...

const multicast = new Subject();
const obs = subject
    .do(console.log)
    .subscribe(multicast);

multicast.subscribe(...);

或这个...

const obs = subject
    .do(console.log)
    .publish();
obs.connect();

或任何取决于你需要什么。

这仅通过一个do()

1
next: 1
next: 1

看下面的代码:

readonly propertyA$ = new BehaviorSubject<string | null>('A');
  readonly propertyB$ = new ReplaySubject<string[] | null>(1);

  constructor(ref: ChangeDetectorRef) {
    setTimeout(() => {
      this.propertyB$.next(['B']);
    }, 2000);

    setTimeout(() => {
      this.propertyB$.next(['B2']);
    }, 3000);

    setTimeout(() => {
      this.propertyA$.next('A2');
    }, 4000);

    setTimeout(() => {
      this.propertyB$.next(['B3']);
    }, 5000);

    setTimeout(() => {
      this.propertyB$.next(['B4']);
    }, 6000);

    setTimeout(() => {
      this.propertyA$.next('A3');
    }, 7000);

    setTimeout(() => {
      this.propertyB$.next(['B5']);
    }, 8000);


    this.propertyA$.pipe(switchMap(propertyA => {
      return this.propertyB$.pipe(
        take(1), //and without
        map(propertyB => ([propertyA, propertyB] as [string, string[]]))
      )
    })).subscribe(x => console.log('propertyA & propertyB (combineLatestFrom): ', x));
}

没有采取(1):

A, B
A, B2
A2, B2
A2, B3
A2, B4
A3, B4
A3, B5

带走(1):

A, B
A2, B2
A3, B4

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM