角等待几个订阅做某事

时间:2018-09-27 13:10:58

标签: angular

在一个组件中,我订阅了两项服务。第一个,

this.myFirstService.currentData.subscribe()

其中currentData来自BehaviorSubject

  private currentDataSource = new BehaviorSubject<any>([]);
  currentData = this.currentDataSource.asObservable();

第二个来自http.get

  getData(): Observable<Data> {
  if(localStorage.getItem('token'))
    var headers = new HttpHeaders({'Authorization':'Bearer ' +   localStorage.getItem('token')});
  else
    var headers = new HttpHeaders({'Authorization':'Anonymous '});

  return this.http.get<Data>("http://someurl/",{
    headers:headers,
    responseType: 'json'
  })
    .pipe();
}

我想合并从两个订阅中接收到的数据。我该如何存档?

3 个答案:

答案 0 :(得分:0)

您可以使用forkJoin合并可观察对象。

  currentData = this.currentDataSource.asObservable();
  httpReq = this.getData();

  forkJoin(currentData, httpReq ).subscribe((result) => {
    // combine results
  })

答案 1 :(得分:0)

“合并”数据是什么意思?

有几种组合可观察流的方法,您可能需要combineLatest运算符。

currentData = this.currentDataSource.asObservable();
httpData = http.getData();
currentData.pipe(combineLatest(httpData))
    .subscribe(([current, http]) => console.log(current, http)); 

答案 2 :(得分:0)

由于您使用的是RxJ,因此有两种方法可以实现:

Concat

Concat会将两个可观察对象合并为一个组合序列,但是第二个可观察对象将在第一个可观察对象完成之前开始发射。

let first = Observable.timer(10,500).map(r => {
  return {source:1,value:r};
}).take(4);
let second = Observable.timer(10,500).map(r => {
  return {source:2,value:r};
}).take(4);
first.concat(second).subscribe(res => this.concatStream.push(res));

这将合并两者,但是您将在第二个之前得到第一个可观察到的结果:

0 1 2 3 0 1 2 3

合并

合并类似于concat,但是它将交错发射的值,而不是在开始第二个可观察值之前先完成第一个可观察值。

let first = Observable.timer(10,500).map(r => {
  return {source:1,value:r};
}).take(4);
let second = Observable.timer(10,500).map(r => {
  return {source:2,value:r};
}).take(4);
first.merge(second).subscribe(res => this.mergeStream.push(res));

您将获得:

0 0 1 1 2 2 3 3 

forkJoin

我们使用forkJoin并行执行可观察对象。一种常见的用例是并行发出多个http请求。在我的示例中,我将ForkJoin加入两个非常简单的可观察变量,但是关键是在两个可观察变量都完成之前,订户将不会收到任何值。

let first = Observable.of({source:1,value:1});
let second = Observable.of({source:2,value:1});
Observable.forkJoin(first,second)
            .subscribe((res:Array) => this.forkJoinStream = res);

这类似于Angular 1.x中的$ q.all()。

最后

flatMap

如果可观察对象之间有依赖性,请使用此选项。假设您必须先获得用户,然后才能通过两个不同的http请求获得用户详细信息:

let first = Observable.of(10);
first.flatMap((operand1) => {
  return Observable.of(operand1 + 10);
})
.subscribe(res => this.flatMappedStreams = {msg: '10 + 10 = ' + res});

您将获得:

10 + 10 = 20