2017-05-16 35 views
7

到「等待」兩個觀測在我的應用程序有類似:我如何在RxJS

this._personService.getName(id) 
     .concat(this._documentService.getDocument()) 
     .subscribe((response) => { 
        console.log(response) 
        this.showForm() 
     }); 

//Output: 
// [getnameResult] 
// [getDocumentResult] 

// I want: 
// [getnameResult][getDocumentResult] 

然後我得到兩分地分居的結果,首先是_personService,然後_documentService的。我怎樣才能等待呼叫this.showForm()前兩個結果完成的操作,然後每一個的結果。

+1

forkJoin https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/forkjoin.md –

+0

什麼我明白了,你已經是,憑藉'concat' – user3743222

+0

@ user3743222在這種情況下,這些值被單獨發射。一個接一個。 – gog

回答

5

Observable.zip(觀測量)

我非常建議Observable.zip方法,它是在reactiveX documentation說明:

組合多個觀測量來創建一個可觀察它們的值是根據其每個輸入觀測值的值按順序計算。

// Results 
name: string; 
document: string; 

// Observables to combine 
const name$ = this._personService.getName(id); 
const document$ = this._documentService.getDocument(); 

Observable 
    .zip(name$, document$, (name: string, document: string) => ({name, document})) 
    .subscribe(pair => { 
      this.name = pair.name; 
      this.document = pair.document; 
      this.showForm(); 
     }) 
在一個側面說明,最後一個參數,在這裏我們提供的功能

(name: string, document: string) => ({name, document})是可選的。您可以跳過它,或執行更復雜的操作:

如果最新參數是一個函數,則使用此函數根據輸入值計算創建的值。否則,返回一個輸入值數組。

所以,如果你跳過最後一部分,你會得到一個數組:可觀察的

// Results 
name: string; 
document: string; 

// Observables to combine 
const name$ = this._personService.getName(id); 
const document$ = this._documentService.getDocument(); 

Observable 
    .zip(name$, document$) 
    .subscribe(pair => { 
      this.name = pair['0']; 
      this.document = pair['1']; 
      this.showForm(); 
     }) 
0

您可以使用「拉鍊」或「緩衝區」像下面這樣。

function getName() { 
    return Observable.of('some name').delay(100); 
} 

function getDocument() { 
    return Observable.of('some document').delay(200); 
} 

// CASE1 : concurrent requests 
Observable.zip(getName(), getDocument(), (name, document) => { 
    return `${name}-${document}`; 
}) 
    .subscribe(value => console.log(`concurrent: ${value}`)); 

// CASE2 : sequential requests 
getName().concat(getDocument()) 
    .bufferCount(2) 
    .map(values => `${values[0]}-${values[1]}`) 
    .subscribe(value => console.log(`sequential: ${value}`)); 
0

查看'combineLatest'方法,在這裏可能適用。 http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-combineLatest

const { Observable } = Rx 

const name$ = this._personService.getName(id); 
const document$ = this._documentService.getDocument(); 

Observable 
    .combineLatest(name$, document$, (name, document) => ({ name, document })) 
    .first() // or not, implementation detail 
    .subscribe(({ name, document }) => { 
     // here we have both name and document 
     this.showForm() 
    }) 
1

對我來說這是sample最好的解決辦法。

const source = Observable.interval(500); 
const example = source.sample(Observable.interval(2000)); 
const subscribe = example.subscribe(val => console.log('sample', val)); 

所以..只有當第二(例如)發出 - 你會看到第一個(源)的最後emited值。

在我的任務,我等形式驗證和其他DOM事件。