我有一个可观察到的动态请求。
例如,
getFlowers(params?: any): Obeservable<Flower[]> {
return this.http.get<Flower[]>(
`http://flowers.com/flowers`, { params }
)
}
现在,上述函数将返回每个观察到的新http
可见的函数。我想以某种方式实现返回相同的可观察实例(尽管进行了不同的http调用),以便可以使用switchMap
来取消先前的同时请求。
我有一个想法,我应该创建一个Observable属性(单例),但是我没有意识到如何利用它。
答案 0 :(得分:1)
现在,上面的函数会在每个函数调用中返回新的http可见的??
这实际上是HTTP
观测对象的正常行为,因为它们是冷的。
当冷observable
具有多个subscribers
时,将为每个subscriber
重新发射整个数据流。每个订户变得独立,并获得自己的数据流
方法:1
为避免HTTP请求重复,您可以使用shareReplay
运算符。
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {Observable} from 'rxjs';
import {shareReplay,tap}from 'rxjs/operators';
@Injectable()
export class ShareService {
public response$:Observable<any>;
constructor(private httpc:HttpClient)
{
this.sendRequest();
}
public sendRequest()
{
this.response$= this.httpc.get('url').
pipe(tap(res=>{console.log('called');return res;}),shareReplay(1))
}
fetchData()
{
return this.response$;
}
}
component1:
constructor(service:ShareService)
{
service.fetchData().subscribe(result=>{
console.log(result);
})
component2:
constructor(service:ShareService)
{
service.fetchData().subscribe(result=>{
console.log(result);
})
Further Reading
Live Demo
方法:2
如果您的目标是多播数据,请使用RXJS的Subject
或BehaviorSubject
Subject
充当源Observable
与许多observers
之间的桥梁/代理,使多个observers
可以共享相同的Observable
执行。
推荐的这种公开主题的方式是使用asObservable()
运算符。
@Injectable()
export class MyProvider {
private myObservable=new Subject<any>();
CurrentData = this.myObservable.asObservable();
constructor(private aFs: AngularFirestore) {
//your logic
this.myObservable.next(value);//push data into observable
}
}
Page.ts
this.mySubscription = this.myProvider.CurrentData.subscribe(value => {
//something that works
});
使用行为主题
@Injectable()
export class MyProvider {
private myObservable=new BehaviorSubject<any>('');
CurrentData = this.myObservable.asObservable();
constructor(private aFs: AngularFirestore) {
}
getData(myParam): void {
someasynccall.pipe(map(),filter()).
subscribe(value=>this.myObservable.next(value))
}
Page.ts
this.myProvider.getData(param);
this.mySubscription = this.myProvider.CurrentData.subscribe(value => {
//something that works
});