我有只调用api的服务类。该服务类正在组件中使用。有没有办法让消耗组件知道何时完成服务api的订阅?
现在,我正在从使用组件向服务发送回调函数。 回调函数是订阅函数的参数之一,据我所知。
class MyService {
constructor(httpClient: HTTPClient){}
fetchDetails (id, callback) {
this.http.get('my/api/endpoint/url').subscribe(
response => {
// do something with response
}
error => { //do some processing for error}
() => callback() // called when subscribe is done
)
}
}
class MyList {
constructor(myservice: MyService){}
getDetails (id) {
this.myservice.fetchDetails(id, this.detailsFetched);
}
detailsFetched () {
// subscribe complete
// do some processing like route to a state
}
}
这目前对我有效,但是我觉得必须有一种更好的方式来做我想做的事。由于我是rxjs的新手,所以我不明白如何实现它。
答案 0 :(得分:0)
您可以在管道中使用rxjs运算符take。这样,您只需订阅可观察对象发出的第一个事件。
fetchDetails (id, callback) {
this.http.get('my/api/endpoint/url').pipe(take(1)).subscribe(
response => {
// do something with response
}
error => { //do some processing for error}
() => callback() // called when subscribe is done
)
}
答案 1 :(得分:0)
您的解决方案是正确的,作为替代方案,我可以建议使用更具声明性的RxJS方式编写此类代码。
import { HttpClient } from '@angular/common/http';
import { shareReplay, finalize } from 'rxjs/operators';
import { Observable } from 'rxjs';
class MyService {
constructor(private http: HttpClient) {}
fetchDetails(id): Observable<any> {
const stream$ = this.http
.get(`my/api/endpoint/url/${id}`)
.pipe(shareReplay());
stream$.subscribe(
(response) => {
console.log(response);
},
(error) => {
console.log(error);
},
() => {
console.log('completed');
},
);
return stream$;
}
}
class MyList {
constructor(private myservice: MyService) {}
private getDetails(id) {
this.myservice
.fetchDetails(id)
.pipe(finalize(() => this.detailsFetched()))
.subscribe();
}
private detailsFetched() {
// subscribe complete
// do some processing like route to a state
}
}
总而言之,您可以看到我正在从Observable
返回fetchDetails()
,shareReplay()
是用shareReplay()
创建的。 getDetails
的作用是,它将仅创建1个网络呼叫并将其共享给订阅可观察源的任何人,然后,如果某人稍后在可观察性完成时进行订阅,它将重播,以便以后的订阅者将收到相同的事件。 / p>
还可以查看finalize()
,在这里我使用{{1}}运算符精确地执行您想要的操作。 当源Observable完成时,将调用传递给finalize运算符的回调。