Angular 角度-订阅多次而不触发多次调用?
我有一个服务调用,其响应缓存在我的Angular服务中,如下所示:Angular 角度-订阅多次而不触发多次调用?,angular,rxjs,Angular,Rxjs,我有一个服务调用,其响应缓存在我的Angular服务中,如下所示: public cacheMyServiceResponse(): Observable<any> { return this.appConfig.getEndpoint('myService') .pipe( switchMap((endpoint: Endpoint) => this.http.get(endpoint.toUrl())), tap((body: any)
public cacheMyServiceResponse(): Observable<any> {
return this.appConfig.getEndpoint('myService')
.pipe(
switchMap((endpoint: Endpoint) => this.http.get(endpoint.toUrl())),
tap((body: any) => {
if (body) { // this endpoint can also return a 204 (No Content), where body is null
this.cache = body.myData;
}
}),
take(1),
catchError(error => {
this.errorService.trackError(error.status);
return of(true);
})
);
}
ngOnInit() {
this.myService.cacheMyServiceResponse().subscribe();
}
但是在其他地方,我需要知道它是否已经完成了调用,而不需要触发我的http调用两次
onClick() {
this.myService.cacheMyServiceResponse().subscribe(() => {
// call is finished..
});
}
目前,该服务将被调用两次。我该怎么做
PS:我没有故意进行错误处理,我只需要知道服务调用是否完成。使用布尔变量检查实际响应的状态,或者我们的调用是否完成(成功或错误);然后,当用户单击按钮时,可以检查此布尔值。。。下面的代码解释我的意思
callMade:boolean = false;
callFinished:boolean = false;
ngOnInit(){
this.callMade = true;
this.myService.cacheMyServiceResponse().subscribe(
dataa => { /* get and process data */}
,() => { /*this is the finally block */
this.callFinished = true;
}
);
}
someOtherFunction(){
if (this.callMade == true && this.callFinished == false){
/* call the service again */
}
}
您可以在此处为您的场景使用
解析器。当你点击你的路线时,它会调用你的方法
例如:
@Injectable()
export class ExampleResolver implements Resolve<any> {
constructor(private apiService: APIService) {}
resolve(route: ActivatedRouteSnapshot) {
return this.apiService.getItems(route.params.date);
}
}
你为什么不保存可观察的
public cacheMyServiceResponse(): Observable<any> {
if(this.cache) {
return of(this.cache);
else if(!this.currentCall) {
this.currentCall = this.appConfig.getEndpoint('myService')
.pipe(
switchMap((endpoint: Endpoint) => this.http.get(endpoint.toUrl())),
tap((body: any) => {
if (body) { // this endpoint can also return a 204 (No Content), where body is null
this.cache = body.myData;
}
}),
take(1),
catchError(error => {
this.errorService.trackError(error.status);
return of(true);
})
);
}
return this.currentCall;
}
public cacheMyServiceResponse():可观察{
if(this.cache){
返回(this.cache);
如果(!this.currentCall){
this.currentCall=this.appConfig.getEndpoint('myService'))
.烟斗(
switchMap((endpoint:endpoint)=>this.http.get(endpoint.toUrl()),
点击((主体:任意)=>{
if(body){//此端点还可以返回204(无内容),其中body为null
this.cache=body.myData;
}
}),
以(1)为例,
catchError(错误=>{
this.errorService.trackError(error.status);
返回(真);
})
);
}
返回此.currentCall;
}
我建议使用并订阅ReplaySubject()
onClick,它将等待您的服务发出数据,而它仍然可以订阅,如果在服务发出数据之前没有订阅,您也不会错过数据:
yourWaitingData = new ReplaySubject();
subscription;
ngOnInit() {
this.myService.cacheMyServiceResponse().subscribe(res => {
//yourWaitingData only emit when res is return from API call
this.yourWaitingData.next(res)
});
}
然后订阅:
onClick() {
if(this.subscription){
this.subscription.unsubscribe()
}
this.subscription = this.yourWaitingData.subscribe((x) => {
// subscribed and will wait for data to be emited from service
console.log(x)
});
}
使用shareReplay
创建一个简单的缓存,该缓存触发http请求一次,并将其返回值提供给缓存中的所有后续订阅
服务
private cache$:Observable首先,在我的示例中,页面加载后也可以调用该按钮,我想在那里等待,比如说最长10秒。因此,我实际上不能只检查一个变量。其次,我问这个问题,希望这可以通过纯rxjs实现。@akcasoy你没有问过最后一部分特别清楚。对不起。但是一旦你接到服务电话,你总是要处理那些还没有回复的情况。在我的问题中,我使用了“.订阅(()”在onClick回调函数中。我想它清楚地表明了我想等待响应,您可以在这里为您的场景使用解析器
。当您点击路由时,它将调用您的方法。示例:@Injectable()导出类APIResolver实现Resolve{constructor(私有apiService:apiService){解析(route:ActivatedRouteSnapshot){返回this.apiService.getItems(route.params.date);}}
{path:'items/:date',component:ItemsComponent,解析:{items:apisresolver}}
它将在您的ngOnInit()之前得到您的响应。此外,您还可以将响应存储在服务缓存中。可能行为主体会更好,否则您可能会错过response@Random感谢您指出,使用ReplaySubject
onClick() {
if(this.subscription){
this.subscription.unsubscribe()
}
this.subscription = this.yourWaitingData.subscribe((x) => {
// subscribed and will wait for data to be emited from service
console.log(x)
});
}