【发布时间】:2019-03-18 17:03:18
【问题描述】:
我有几个相互依赖的 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 调用——我愿意接受有关@987654333 更流畅方式的建议@out Observable 链。
【问题讨论】:
-
那是
Observable上极其复杂的运算符链。您的问题缺乏关于您在 Operators 中完成的几个函数调用将返回什么的实现细节。您能否考虑创建一个 StackBlitz 来复制此问题? -
@SiddAjmera 因此我可以使用一些帮助:)。文档和其他方面给出的示例非常简单。我想我可以尝试 StackBlitz,但我不确定如何在没有真正调用的情况下复制它(我们的后端位于 Okta 之后)。那些其他函数调用都正确返回;我也可以包括它们。我希望有人能帮我发现一个明显的逻辑错误。
-
@kriskanya
return observableForkJoin()是什么? -
@kriskanya 好的,如果问题仅在放置该行代码时出现,那么。我建议检查这些以查看它们是否正常工作。您实际的 http 调用似乎很好。
project_program_id: parseInt(projectId, 10),value: this.getProjectPhase(this.activities)。这些可能是异步抛出的,因此您看不到任何控制台输出。
标签: angular typescript rxjs reactive-programming