我有几个相互依赖的 API 调用。具体来说,我无法让最终的 Observable 正确返回:它会导致应用程序无限期滞后。
如果我自己调用 this.projectAttributeService.findAndUpdateByProjectAndMetumId({...})
然后 .subscribe
它似乎工作正常。这表明这是我在前端的 Observable 链接的问题。目前,该方法甚至没有在后端调用(我设置了一个断点)。
//.服务
submitPhasesForm(projectId) {
return this.activityDateService.activities$.pipe(
first(),
concatMap((activities: ActivityDate[]) => {
this.activities = activities;
if (this.activities.length === 0) {
return observableOf({});
}
this.activities = activities.map(a => {
a.project_program_id = parseInt(projectId, 10);
return a;
});
return this.activityDateService.update(this.activities);
}),
mergeMap(() => {
if (this.activities.length === 0) {
return observableOf({});
}
return this.projectAttributeService.getAllMetadata(3).pipe(first())
}),
mergeMap((metaData: ProjectAttMetadataAPIResponse) => {
if (this.activities.length === 0) {
return observableOf({});
}
const metaDataId = (metaData as any).find(m => m.name === 'Phase').id;
// EDIT: the problem ended up being with the synchronous
// this.getProjectPhase(this.activities) method below
return this.projectAttributeService.findAndUpdateByProjectAndMetumId({
project_program_id: parseInt(projectId, 10),
value: this.getProjectPhase(this.activities),
project_attrib_metum_id: metaDataId
})
})
)
}
这就是 findAndUpdateByProjectAndMetumId()
的样子(调用本身似乎工作正常):
findAndUpdateByProjectAndMetumId(body: ProjectAttribute): Observable < ProjectAttribute > {
return this.http.put < ProjectAttribute > (`${ environment.API_URL }project-attribute`, body);
}
这就是调用 submitPhasesForm()
的地方:
//.组件
import { forkJoin as observableForkJoin } from 'rxjs';
return this.projectService.patch(this.projectId, {
summary: projectSummary || proj.summary
}).pipe(
first(),
mergeMap(() => {
return observableForkJoin(
this.phasesFormDataService.submitPhasesForm(this.projectId).pipe(first()),
this.pdpMetricsFormService.submitPdpForm(this.projectId).pipe(first()),
this.projectStatusFormService.submitStatusForm(this.projectId).pipe(first())
)
})
)
.subscribe((res) => {
this.router.navigate([`./pdp/${this.currentTab}/${this.projectId}`]);
});
另外两个调用非常相似,尽管更短:
submitPdpForm(projectId) {
return this.pdpMetricsForm$.pipe(
first(),
concatMap((formGroup: FormGroup) => {
if (!formGroup.get('etRadioModel')) {
return observableOf({});
}
const objSend = {...}
return this.projectService.upsertPdpMetrics(projectId, objSend);
})
)
}
...
submitStatusForm(projectId) {
return this.metrics$.pipe(
first(),
tap(metrics => {
this.metricsData = metrics;
}),
mergeMap(() => this.statusesForm$),
observableMap(statusesForm => {
const formGroup = statusesForm;
if (!formGroup.get('resourceRationale')) {
return {};
}
const obj = [{...}]
return sendObj;
}),
mergeMap((sendObj: any) => {
if (isEmpty(sendObj)) { return observableOf(sendObj) };
return this.projectService.upsertMetrics(projectId, sendObj).pipe(first());
})
)
我链接或调用这些 Observable 的方式看起来有什么问题吗?
非常感谢任何帮助!
如果第一个 activities$
Observable 没有产生数据,我将返回 of({})
,这样我就可以通过 Observable 流,而不会进行不必要的 API 调用 - -- 我乐于接受有关以更流畅的方式打破
Observable 链的建议。
最佳答案
原来我的同步 this.getProjectPhase(this.activities)
方法有一个逻辑错误,它使应用程序进入无限循环。
否则,Observable 运算符工作正常。
如果 this.activities
为空,我仍然想找出一种更流畅的方法来跳出该流。
关于angular - 如何在一系列 API 调用中正确链接可观察对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52796900/