因此,我认为这是一个相当复杂的Rxjs管道可观测流,如下所示。一切都很好,但在我发表评论的那一部分
//这是IT开始变得有点疯狂的地方
我开始觉得有点奇怪了。问题是,在这一点上,如果addressUsage类型是point,我们需要发出另一个网络请求,然后最终显示一个模式(然后需要订阅),而对于任何其他类型的地址,在这一点上不需要更多的东西。
因此,为了满足这一需要,我开始从开关映射返回(Null)或of([]),除非它的邮政地址类型是什么时候返回的。这样可以实现我所需要的功能,但感觉非常错误。是否有一种更好/更易读的方式来实现这个功能?
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);
});
发布于 2022-08-05 15:30:03
您可能想要考虑使用可观测的EMPTY
,即不发射任何东西并立即完成的可观测的。
代码将如下所示
//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
发布于 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}))
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);
});
https://stackoverflow.com/questions/73250969
复制相似问题