是否可以在 rxjs 6 和 angular 中共享订阅事件?
Is it possible to share subscribe event in rxjs6 and angular?
我有服务 class,它只是调用 api。此服务 class 正在组件中使用。有没有办法让消费组件知道服务 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 的新手,所以我无法理解如何实现它。
您可以在管道中使用 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
)
}
您的解决方案是正确的,作为替代方案,我可以建议使用更具声明性的 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
}
}
总而言之,您可以看到我从使用 shareReplay()
创建的 fetchDetails()
返回 Observable
。 shareReplay()
所做的是它只会创建 1 个网络调用并将其共享给订阅源 observable 的任何人,然后如果有人在 observable 完成后订阅,它将重播以便后来的订阅者将收到相同的事件。
另请查看 getDetails
,我在其中使用 finalize()
运算符来执行您想要的操作。 传递给 finalize 运算符的回调将在源 Observable 完成时被调用。
我有服务 class,它只是调用 api。此服务 class 正在组件中使用。有没有办法让消费组件知道服务 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 的新手,所以我无法理解如何实现它。
您可以在管道中使用 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
)
}
您的解决方案是正确的,作为替代方案,我可以建议使用更具声明性的 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
}
}
总而言之,您可以看到我从使用 shareReplay()
创建的 fetchDetails()
返回 Observable
。 shareReplay()
所做的是它只会创建 1 个网络调用并将其共享给订阅源 observable 的任何人,然后如果有人在 observable 完成后订阅,它将重播以便后来的订阅者将收到相同的事件。
另请查看 getDetails
,我在其中使用 finalize()
运算符来执行您想要的操作。 传递给 finalize 运算符的回调将在源 Observable 完成时被调用。