【问题标题】:RxJS multiple switchMap and map operators... is there a better way?RxJS 多个 switchMap 和 map 运算符...有更好的方法吗?
【发布时间】:2018-09-19 20:22:11
【问题描述】:

我对 RxJS 还是很陌生,想知道我这样做是否正确……在下面的 ngOnInit() 函数中,我得到一个客户端对象,然后通过管道传输它……

有没有更好的方法来执行下面的重复 switchMap/map 操作?

我的代码有效...但我想知道是否有更优雅的方法我应该采用...

public client: Client;
public contract: Contract;      
public alreadyPendingContract: boolean;
public alreadyActiveContract: boolean;
public minimumStartDate: Date;
public minimumEndDate: Date;
public rolloverExclusionDate: Date;
public startDateFilter;

  ngOnInit() {
    this.clientService.getClient$().pipe(
      filter(client => client != null),
      map(client => this.client = client),
      pluck('client_id'),
      map((client_id: string) => {
        this.clientContractForm.get('client_id').setValue(client_id);
        return client_id;
      }),
      switchMap((client_id: string) => {
        return this.contractAddService.getAlreadyPendingContract$(client_id);
      }),
      map(alreadyPendingContract => {
        this.alreadyPendingContract = alreadyPendingContract;
        return this.client.client_id;
      }),
      switchMap((client_id: string) => {
        return this.contractAddService.getAlreadyActiveContract$(client_id);
      }),
      map(alreadyActiveContract => {
        this.alreadyActiveContract = alreadyActiveContract;
      }),
      switchMap(() => {
        return this.contractAddService.getMinimumStartDate$(this.client.client_id);
      }),
      map((minimumStartDate: IMinimumStartDate) => {
        this.minimumStartDate = minimumStartDate.minimumStartDate;
        this.rolloverExclusionDate = minimumStartDate.rolloverExclusionDate;
        this.startDateFilter = (m: Moment): boolean => {
          // Filters out the rollover exclusion day from being an available start date.
          return !moment.utc(m).isSame(moment.utc(this.rolloverExclusionDate), 'day');
        }
      })
    ).subscribe();
  }

【问题讨论】:

  • 您的switchMaps 会依次跟随另一个(在我看来)它们可以与某种flatMap 并行运行。它们都只使用客户端 ID 作为输入,因此它可能只是一组 并行 调用
  • 我看不出你的代码有什么问题,你说的更优雅的方式是什么意思?

标签: rxjs rxjs-pipeable-operators


【解决方案1】:

我不确定这是否更优雅,但它是另一种方式

ngOnInit() {
    this.clientService.getClient$().pipe(
      filter(client => client != null),
      map(client => {
         this.client = client;
         this.clientContractForm.get('client_id').setValue(client_id);
         return client.client_id;
      },
      switchMap(client_id => this.doStuffWithClientId(client_id)),
      map((minimumStartDate: IMinimumStartDate) => {
        this.minimumStartDate = minimumStartDate.minimumStartDate;
        this.rolloverExclusionDate = minimumStartDate.rolloverExclusionDate;
        this.startDateFilter = (m: Moment): boolean => {
          // Filters out the rollover exclusion day from being an available start date.
          return !moment.utc(m).isSame(moment.utc(this.rolloverExclusionDate), 'day');
        }
      })
    ).subscribe();
  }

doStuffWithClientId(clientId: string) {
   return this.contractAddService.getAlreadyPendingContract$(client_id).pipe(
      tap(alreadyPendingContract => this.alreadyPendingContract = alreadyPendingContract),
      switchMap(() => this.contractAddService.getAlreadyActiveContract$(clientId)),
      tap(alreadyActiveContract => this.alreadyActiveContract = alreadyActiveContract),
      switchMap(() => this.contractAddService.getMinimumStartDate$(clientId)),
   )
}

我没有测试过代码,所以很可能有语法错误。基本思想是将所有依赖于 client_id 的东西隔离到一个函数中,该函数接收 clientId 作为输入,因此使其在整个函数中可见。

【讨论】:

  • 你好@Picci,地图管道的目标是转换原始输入,而不是在属性或任何特征中存储值。请优先使用为此设计的tap 管道。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多