首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >有没有办法整顿这条rxjs操作符链?

有没有办法整顿这条rxjs操作符链?
EN

Stack Overflow用户
提问于 2022-08-05 14:00:08
回答 2查看 42关注 0票数 0

因此,我认为这是一个相当复杂的Rxjs管道可观测流,如下所示。一切都很好,但在我发表评论的那一部分

//这是IT开始变得有点疯狂的地方

我开始觉得有点奇怪了。问题是,在这一点上,如果addressUsage类型是point,我们需要发出另一个网络请求,然后最终显示一个模式(然后需要订阅),而对于任何其他类型的地址,在这一点上不需要更多的东西。

因此,为了满足这一需要,我开始从开关映射返回(Null)或of([]),除非它的邮政地址类型是什么时候返回的。这样可以实现我所需要的功能,但感觉非常错误。是否有一种更好/更易读的方式来实现这个功能?

代码语言:javascript
运行
复制
this.entitiesManagementService.searchAddressEventEmitter$.pipe(filter((addressUsage: AddressUsage) => {
  if (this.addressAttributesSearchForm.valid && addressUsage === this.addressUsage) {
    return true;
  } else {
    this.addressAttributesSearchForm.markAllAsTouched();
    return false;
  }
})).pipe(this.takeUntilDestroyed(), switchMap((_) => {
  return forkJoin([
    this.entitiesManagementService.getAddressClassification(<payload>),
    this.entitiesManagementService.searchAddress(<payload>),
  ]);
})).pipe(switchMap(([fields, searchResults]) => {
  const addressFieldDetails = fields[0].addressFieldDetailDetails;

  const dialogRef = this.modalService.open(SelectAddressModalComponent, {
    data: searchResults.genericAddressDetail.genericAddress,
  });
  return forkJoin([dialogRef.afterClosed(), of(addressFieldDetails)]);
}))
  .pipe(filter(([selectedAddress, _]) => selectedAddress !== ''))
  .pipe(switchMap(([selectedAddress, fields]: [GenericAddress, AddressFieldConfig[]]) => {
  //THIS IS WHERE IT STARTS GETTING A BIT CRAZY
    if (this.addressUsage === AddressUsage.POSTAL) {
      const formValue = this.addressAttributesSearchForm.getRawValue();
      const postalCode = selectedAddress.addressField.find(field => field.addressFieldName === 'POST_CD')!.addressFieldValue;
      const suburb = selectedAddress.addressField.find(field => field.addressFieldName === 'SUBURB')!.addressFieldValue;
      return forkJoin([this.entitiesManagementService.getSuburbInformation(this.componentName, new SearchAreaDetailsPayload(this.getKeyByValue(formValue.classification), this.addressUsage, postalCode, suburb)), of(selectedAddress), of(fields)]);
    } else if (selectedAddress.description === 'createExceptionAddress') {
      this.goToExceptionForm();
      return forkJoin([]);
    } else {
      this.selectedDocId = selectedAddress.docID;
      this.setupFormValidatorsAndPrepopFields(fields, selectedAddress.addressField);
      return forkJoin([]);
    }
  })).pipe(switchMap(([suburbInformation, selectedAddress, fields]) => {
  if (suburbInformation !== null) {
    const dialogRef = this.modalService.open(SelectSuburbModalComponent, {
      width: '900px',
      height: '600px',
      panelClass: 'mat-dialog-override',
      data: suburbInformation?.areaDetails?.postalAddress ?? [],
    });

    return forkJoin([dialogRef.afterClosed(), of(selectedAddress), of(fields)]);
  } else {
    return of([]);
  }
})).subscribe(([selectedSuburb, selectedAddress, fields]) => {
  this.selectedDocId = selectedAddress.docID;
  this.setupFormValidatorsAndPrepopFields(fields, selectedAddress.addressField, selectedSuburb);
});
EN

回答 2

Stack Overflow用户

发布于 2022-08-05 15:30:03

您可能想要考虑使用可观测的EMPTY,即不发射任何东西并立即完成的可观测的。

代码将如下所示

代码语言:javascript
运行
复制
//THIS IS WHERE IT STARTS GETTING A BIT CRAZY
    if (this.addressUsage === AddressUsage.POSTAL) {
      ....
      return forkJoin([this.entitiesManagementService.getSuburbInformation(this.componentName, new SearchAreaDetailsPayload(this.getKeyByValue(formValue.classification), this.addressUsage, postalCode, suburb)), of(selectedAddress), of(fields)]);
    } else if (selectedAddress.description === 'createExceptionAddress') {
      this.goToExceptionForm();
    } else {
      this.selectedDocId = selectedAddress.docID;
      this.setupFormValidatorsAndPrepopFields(fields, selectedAddress.addressField);
    }
    // here you return EMPTY
    return EMPTY
票数 0
EN

Stack Overflow用户

发布于 2022-08-05 15:42:38

你大部分的复杂性看起来都是偶然的。对于手头的领域来说,这并不是非常重要的,而是对于您如何构建您的程序。从您在这里展示的代码片段中无法真正解决这个问题。

从您已经展示的情况来看,只需不对pipe进行冗余调用,就可以消除一些杂乱。

在语义上,forkJoin([])EMPTY是相同的。他们什么也不排放,马上就完成。对于清晰性和类型检查目的,EMPTY是更好的选择。

forkJoin与一堆of(a), of(b), of(c)调用一起工作,作为一种组合值的方法,但是在任何地方包装一个可观察到的单值展开都是一种额外的仪式。只要将这样的值直接映射到流中,就可以将其映射到仍然在作用域中的流中。

这样做的限制性也稍小一些。例如,当我在映射之前过滤selectedAddress (而不是以后销毁过滤器的输入)。它还允许您以既不是元组也不是数组的格式构造我们的数据。

例如:

map(selectedAddress => [selectedAddress, addressFieldDetails])

可能是JavaScript Object,而不是:

map(selectedAddress => ({address: selectedAddress, details: addressFieldDetails}))

代码语言:javascript
运行
复制
this.entitiesManagementService.searchAddressEventEmitter$.pipe(

  filter((addressUsage: AddressUsage) => {
    if (this.addressAttributesSearchForm.valid && addressUsage === this.addressUsage) {
      return true;
    }

    this.addressAttributesSearchForm.markAllAsTouched();
    return false;
  }),

  this.takeUntilDestroyed(),

  switchMap(_ => forkJoin([
    this.entitiesManagementService.getAddressClassification<payload>(),
    this.entitiesManagementService.searchAddress<payload>()
  ])),

  switchMap(([[{addressFieldDetails}], searchResults]) => {
    const dialogRef = this.modalService.open(SelectAddressModalComponent, {
      data: searchResults.genericAddressDetail.genericAddress,
    });
    return dialogRef.afterClosed().pipe(
      filter(selectedAddress => selectedAddress !== ''),
      map(selectedAddress => [selectedAddress, addressFieldDetails])
    );
  }),

  switchMap(([selectedAddress, fields]: [GenericAddress, AddressFieldConfig[]]) => {
    if (this.addressUsage === AddressUsage.POSTAL) {
      const formValue = this.addressAttributesSearchForm.getRawValue();
      const postalCode = selectedAddress.addressField.find(field => field.addressFieldName === 'POST_CD')!.addressFieldValue;
      const suburb = selectedAddress.addressField.find(field => field.addressFieldName === 'SUBURB')!.addressFieldValue;
      return this.entitiesManagementService.getSuburbInformation(
        this.componentName, 
        new SearchAreaDetailsPayload(this.getKeyByValue(formValue.classification), 
        this.addressUsage, 
        postalCode, 
        suburb)
      ).pipe(
        map(suburbInformation => [suburbInformation, selectedAddress, fields])
      );
    } else if (selectedAddress.description === 'createExceptionAddress') {
      this.goToExceptionForm();
    } else {
      this.selectedDocId = selectedAddress.docID;
      this.setupFormValidatorsAndPrepopFields(fields, selectedAddress.addressField);
    }
    return EMPTY;
  }),

  filter(([suburbInformation]) => suburbInformation !== null),

  switchMap(([suburbInformation, selectedAddress, fields]) => {
    const dialogRef = this.modalService.open(SelectSuburbModalComponent, {
      width: '900px',
      height: '600px',
      panelClass: 'mat-dialog-override',
      data: suburbInformation?.areaDetails?.postalAddress ?? [],
    });
    return dialogRef.afterClosed().pipe(
      map(selectedSuburb => [selectedSuburb, selectedAddress, fields])
    );
  })

).subscribe(([selectedSuburb, selectedAddress, fields]) => {
  this.selectedDocId = selectedAddress.docID;
  this.setupFormValidatorsAndPrepopFields(fields, selectedAddress.addressField, selectedSuburb);
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73250969

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档