Angular 2为什么我的4 api调用不会等待之前的调用在执行前完成?
我有一个form
/component
必须做4个独立的API调用才能执行“保存”。真的,这些交易中只有一个需要等待其他3个交易,但我想要将所有4个交易链接起来以保证安全。Angular 2为什么我的4 api调用不会等待之前的调用在执行前完成?
以下是我把它设置:
save() {
this.save1(saveObject1)
.subscribe(response => {
if (response === 0) {
this.processErrorResult('save1');
}
this.save2(saveObject2)
.subscribe(response2 => {
if (response2 === 0) {
this.processErrorResult('save1');
}
this.save3(saveObject3)
.subscribe(response3 => {
if (response3 === 0) {
this.processErrorResult('save1');
}
if (this.noErrorsInFirst3Saves()) {
this.save4(saveObject4)
.subscribe(response4 => {
if (response4 === 0) {
this.processErrorResult('save1');
}
if (!this.hasErrors()) {
this.router.navigate(['confirmation']);
}
});
}
});
});
});
}
private save1(saveObject: any): Observable<int> {
this.api.save1(saveObject)
.subscribe(successful => {
return Observable.of(1);
}, failed => {
return Observable.of(0);
});
}
private save2(saveObject: any): Observable<int> {
this.api.save2(saveObject)
.subscribe(successful => {
return Observable.of(1);
}, failed => {
return Observable.of(0);
});
}
private save3(saveObject: any): Observable<int> {
this.api.save3(saveObject)
.subscribe(successful => {
return Observable.of(1);
}, failed => {
return Observable.of(0);
});
}
private save4(saveObject: any): Observable<int> {
this.api.save4(saveObject)
.subscribe(successful => {
return Observable.of(1);
}, failed => {
return Observable.of(0);
});
}
每个里面那些save{number}
功能我有日志消息,所以我清楚地知道,这些功能得到执行(和响应回来)的顺序。
当我点击保存,它[几乎]立即重定向到我的确认页面,然后我就可以坐在那里,看着在Chrome浏览器开发工具,我的控制台窗口,看到来电开始进来的API响应。
为什么这个设置不接受这些事务的显式链接?我知道在Angular
1中,用promise
做这个很容易,并且做了.then(response => {});
。
,我能想到的,是唯一不同的,是每个API调用,不管它是一个get
/post
/put
/delete
,它总是显示在Chrome浏览器开发工具,网络面板2所调用。第一个呼叫的RequestMethod
设置为Options
,而随后的呼叫是相应设置的RequestMethod
,对应的get
/post
/put
/delete
。
我不记得曾经在我最近的任何应用程序中看到这些(重复调用),(也许我只是从未注意过太多),所以也许这只是API的标准操作过程调用。
这里的任何想法?
编辑:针对哈利的建议答复如下
我想实现你的答案,但还是有点困惑就如何实施,这里是我的设置仔细一看:
private save1(saveObject: any): Observable<number> {
if (saveObject.hasChanges()) {
return this.api.save1(saveObject)
.map(successful => {
return this.parseSaveResponse(successful, saveObject, true); // true indicates a successful API response
})
.catch(failed => {
return this.parseSaveResponse(successful, saveObject, false); // false indicates a successful API response
});
} else {
return Observable.of(-1); // no changes necessary, return immediately
}
}
private parseSaveResponse(response: any, saveObject: any, transactionSuccessful: boolean) {
this.logService.logTransaction({transactionType}, saveObject, response, transactionSuccessful);
if (!transactionSuccessful) {
// add to error list object to be displayed on the form
return 0;
}
return 1;
}
当得到这一点,它抛出我的错误就行.catch({});
说:
Argument of type '(error: any) => 0 | 1' is not assignable to parameter of type '(err: any, caught: Observable<0 | 1>) => ObservableInput<{}>'. Type '0 | 1' is not assignable to type 'ObservableInput<{}>'. Type '0' is not assignable to type 'ObservableInput<{}>'.)
的Theres相当多的问题。首先,您的save1/save2/save3方法应该只返回您可以订阅的API中的observable。
其次,您正在使用TypeScript中不存在的int类型。使用号码。
private save1(saveObject: any): Observable<number> {
return this.api.save1(saveObject);
}
// or
private save1(saveObject: any): Observable<number> {
return this.api.save1(saveObject).map(response => 1).catch(response => 0)
}
如果你想修改发射,你可以添加地图操作它映射发射到别的项目的项目。
最后,您应该避免从observable内部订阅observable。您可以使用运算符将observables链接在一起。这将Observable发射的物品转换为Observable,然后将这些物品的排放物变成单个Observable。
save() {
this.save1(saveObject1)
.flatMap(response1 => this.save2(saveObject2))
.flatMap(response2 => {
if (response2 === 0) {
// handle error
}
return this.save3(saveObject3);
})
.flatMap(() => this.save4(saveObject4))
.subscribe(response4 => {
// do redirect
});
}
我认为你需要“返回”你的观察对象。例如:
更改此:
this.api.save1(saveObject)
要:与您的代码可能是导致
return this.api.save1(saveObject)
,即使这些'this.api.save1()'调用都有一个'.subscribe',并且它们正在执行'return Observable.of({number });'? – ganders
@ganders是的。你需要返回 – vidalsasoon
一旦我添加返回你说的,vscode抛出整个块下的红色错误行说:'类型订阅不可分配到类型Observable
的面貌迈向switchmap算符变换rxjs到链您的来电。它可以将Observable作为输入,并且可以使用它来调用其他API。如果您想等待,您可以查看Observable.forkJoin方法 – DOMZE