如何创建发出动态请求的http observable

时间:2018-10-09 09:02:40

标签: angular rxjs

我有一个可观察到的动态请求。

例如,

getFlowers(params?: any): Obeservable<Flower[]> {
  return this.http.get<Flower[]>(
    `http://flowers.com/flowers`, { params }
  )
}

现在,上述函数将返回每个观察到的新http可见的函数。我想以某种方式实现返回相同的可观察实例(尽管进行了不同的http调用),以便可以使用switchMap来取消先前的同时请求。

我有一个想法,我应该创建一个Observable属性(单例),但是我没有意识到如何利用它。

1 个答案:

答案 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的SubjectBehaviorSubject
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