简体   繁体   中英

How to wait for observable to finish? Angular 2

I have multiple calls that are being made and need to wait for all of them to finish before I can route to a different page. The problem I am running into is that typically I have been nesting web service calls, but for this case I have separate calls that may or may not be called based on input by the user. How do I wait for all calls that may or may not be called before routing to a new page.

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
      }
    );   
}

I am new to observables, so I'm not sure what the best way of doing this would be. Thanks for the help!

you could using 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

or concat or merge:

The concat() stream will print all of the values from source1 first, and only begin printing values from source2 after source1 completes.

The merge() stream will print values from source1 and source2 as it receives them: It won't wait for the first stream to complete before emitting values from the second.

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);
  });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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