如何等待观察完成? Angular 2

时间:2017-02-06 00:27:13

标签: angular typescript rxjs observable

我有多个正在进行的调用,需要等待所有这些调用才能完成,然后才能路由到另一个页面。我遇到的问题是通常我一直在嵌套Web服务调用,但是对于这种情况,我有单独的调用,可能会也可能不会根据用户的输入调用。在路由到新页面之前,如何等待可能会或可能不会调用的所有呼叫。

submitButton_Clicked() {
  this.busy = this.service.call1() // must be called
    .first().subscribe(
      if (success){

        // **Logic to decide if call 2 is needed**
        ...

        this.busy = this.service.call2() // might be called
          .first().subscribe();

        // **Logic to decide if call 3 is needed**
        ...

        this.busy = this.service.call3() // might be called
          .first().subscribe();

        this.router('route'); // should route after all potential calls
      }
    );   
}

我是观察者的新手,所以我不确定这样做的最佳方法是什么。谢谢您的帮助!

1 个答案:

答案 0 :(得分:1)

你可以使用flatMap

let Observable = Rx.Observable;

let f = Observable.of(20).delay(1000);
let g = f.map(x => x*x)
  .flatMap(x => Observable.of(x + 100));

g.subscribe(console.log);


/** 
 * Rx.Observable.prototype.flatMap 
 * and Rx.Observable.prototype.selectMany 
 * are equivalent.
 */

let h = f.map(x => x*3)
  .delay(1000)
  .flatMap(x => Observable.of(x + 100));
h.subscribe(console.log);

https://jsbin.com/vokofug/edit?js,console,output

或concat或merge:

  

concat()流将首先打印source1中的所有值,   并且只在source1完成后才开始从source2打印值。

     

merge()流将打印来自source1和source2的值   接收它们:它不会等待第一个流之前完成   从第二个发射值。

http://codepen.io/SitePoint/pen/PzKdVQ

'use strict';

const source1 =
  Rx.Observable.interval(100)
    .map(val => `Source 1: ${val}`)
    .take(5);

const source2 =
  Rx.Observable.interval(100)
    .map(val => `Source 2: ${val * 10}`)
    .take(5);

const concat_table = $('#concat-table-body'),
      merge_table  = $('#merge-table-body');

source1
  .concat(source2)
  .subscribe(value => {
    const row = document.createElement('tr');
    row.innerHTML = value;

    // Source 1 values populate BEFORE Source 2 
    concat_table.append(row);
  });

source1
  .merge(source2)
  .subscribe(value => {
    const row = document.createElement('tr');
    row.innerHTML = value;

    // Source 1 values INTERLEAVE with Source 2
    merge_table.append(row);
  });