繁体   English   中英

Observable 之 Angular/RxJS 多播 Observable

[英]Angular / RxJS Multicasting Observable of Observable

我有一个 HTTP 请求,我想将其结果共享给多个组件。 当然,HTTP 请求会返回一个Observable 我希望多个组件能够订阅它而不会触发额外的 HTTP 请求。

我使用组件中的Subject完成了这一点,该组件按需发出 HTTP 请求,并有另一种订阅主题的方法。 虽然这有效 - 这似乎有点矫枉过正,当然有更好的方法来做到这一点。

学科服务

@Injectable()
export class EventService {
    subject: BehaviorSubject<any> = new BehaviorSubject<any>(Observable.create());

    constructor(private api: Api) {}

    fetch = () => {
        this.subject.next(
            this.api.getUsers().pipe(share())
        );
    };

    listen = (): Observable<any> => {
        return this.subject.asObservable();
    };
}

和一名订阅者

@Injectable
export class EventListenerA {
    constructor(private eventService: EventService){
        eventService.fetch(); // make initial call
        eventService.listen().subscribe(o => {
             o.subscribe(httpResponse => {
                 //do something with response
             })
        });
    }
}

和第二个订阅者

@Injectable
export class EventListenerB {
    constructor(private eventService: EventService){
        eventService.listen().subscribe(o => {
             o.subscribe(httpResponse => {
                 //do something else with response
             })
        });
    }
}

当我从管道链中删除share() ,会发出多个网络请求。 是否有更优雅/正确的方法将 observable 传递给Subjectnext一个? 或者完全是另一种模式

您应该使用ReplaySubject()而不给它一个初始值。 这样,当组件订阅listen() ,它将等待直到有可用数据。

无需与其他组件共享HTTP observable。 只需订阅 HTTP 请求,然后将值发送到ReplaySubject() 任何侦听的组件都将接收数据。

@Injectable()
export class EventService {
     private _events: ReplaySubject<any> = new ReplaySubject(1);

     public constructor(private _api: ApiService) {}

     public fetch() {
         this.api.getUsers().subscribe(value => this._events.next(value));
     }

     public listen() {
         return this._events.asObservable();
     }
 }

 @Injectable
 export class EventListenerA {
     constructor(private eventService: EventService){
          eventService.fetch();
          eventService.listen().subscribe(o => {
              // prints user data
              console.log(o); 
          });
     }
}

每次有人调用eventService.fetch()都会触发一个 HTTP 请求。 如果您想执行一次此请求,则可以从服务构造函数或应用程序中仅发生一次的其他位置(即模块构造函数)调用fetch() )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM