我正在使用HTTPClient
发出post
请求,但是当我subscribe
对observable
返回的HTTPClient
时却遇到了很奇怪的行为:对于每个{ {1}},我收到一个subscription
请求。意思是,如果我post
至subscribe
5次,则我收到5个observable
请求。太不可思议了!
我正在 post
中进行发帖请求,如下所示:
serverService
在我的组件中,我按以下方式致电 makePostReq<T>(reqObj: {url:string, body:any, headerData?:any}): Observable<T>{
let headers = this.createHeaders(reqObj.headerData);
reqObj.body, {headers:headers});
return this.httpClient.post<T>(reqObj.url, reqObj.body, {headers:headers});
}
:
makePostReq
截屏:
编辑:
实际上,我没有多次订阅。相反,我在模板中使用了 overviewInfo$: Observable<IOverviewInfo>;
ngOnInit() {
this.getOverviewInfo();
}
getOverviewInfo() {
console.log('getOverviewInfo...');
let url = this.constantsService.getOverViewInfoUrl();
let body = {
bot_id: this.bot_id,
platform: this.selectedChannel,
start_date: this.start_date,
end_date: this.end_date
};
this.overviewInfo$ = this.serverService.makePostReq({url, body});
/*=== Now if I subscribe to overviewInfo 5 times, I will have 5 post request=== */
this.overviewInfo$.subscribe((value) => {
console.log(value);
});
this.overviewInfo$.subscribe((value) => {
console.log(value);
});
this.overviewInfo$.subscribe((value) => {
console.log(value);
});
this.overviewInfo$.subscribe((value) => {
console.log(value);
});
this.overviewInfo$.subscribe((value) => {
console.log(value);
});
}
5次,其效果与调用(overviewInfo$|async)
5次相同。我问了多个POST
以减少subscribe
管道不必要的复杂性的问题。
答案 0 :(得分:2)
我相信您面对的是寒冷。 post
方法创建一个可观察对象,该观察对象等待其被订阅,直到激发请求为止。
从post()
的角度documentation起
构造一个Observable,当订阅时,它将导致已配置的POST请求在服务器上执行。
根据要实现的目标,可以使用share
运算符。每个订阅都不会触发新的发布请求,但是在发布请求完成后,它将获得相同的数据。同样,它不会在订阅某些内容之前触发发布请求。如果您在请求完成后订阅,则应该重新创建一个请求。
this.overviewInfo$ = this.serverService
.makePostReq({url, body})
.pipe(share());
multicast
运算符可以实现略有不同的行为,它将立即触发发布请求。如果您在请求完成后订阅,则不会收到任何数据。
this.overviewInfo$ = this.serverService
.makePostReq({url, body})
.pipe(multicast());
要保证良好的承诺时间,可以使用toPromise
,.then
可以随时使用。
有关上述运算符的更多信息:RxJS: Understanding the publish and share Operators
答案 1 :(得分:1)
我不知道您为什么在同一文件中多次订阅同一方法。相反,您只能有一个subscription
并在那里做所有的工作。您的组件代码调用了makePostReq
5次,这是正常现象。
无论哪种方式,如果您想多次订阅一个可观察的节目,并且只想触发http.post
一次,那么Subject
或BehaviourSubject
最适合您的要求。
以this._subOverviewInfo.next(res.name))
的身份发送服务中的数据
服务器服务
private _subOverviewInfo: Subject<string> = new Subject<string>();
public overViewInfo$: Observable<string> = this._subOverviewInfo.asObservable();
makePostReq<T>(reqObj: {url:string, body:any, headerData?:any}): Observable<T>{
let headers = this.createHeaders(reqObj.headerData);
reqObj.body, {headers:headers});
return this.httpClient.post<T>(reqObj.url, reqObj.body, {headers:headers})
.pipe(map((res) => {
this._subOverviewInfo.next(res.name); // emit subject
return res;
}));
}
在组件中
按原样致电makePostReq()
this.serverService.makePostReq({url, body}).subscribe();
相反,订阅服务所授予的subject
。
this.serverService.overViewInfo$.subscribe((value) => {
console.log(value);
});
this.serverService.overViewInfo$.subscribe((value) => {
console.log(value);
});
this.serverService.overViewInfo$.subscribe((value) => {
console.log(value);
});