Теперь вышеприведенная функция возвращает новую 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$;
}
}
компонент1:
constructor(service:ShareService)
{
service.fetchData().subscribe(result=>{
console.log(result);
})
компонент2:
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
});
Subject vs BehaviorSubject
LiveDemo