2016-05-02 148 views
13

對於在TypeScript中使用Angular2編寫的Web應用程序,我需要使用RxJs Observable s。
因爲我從來沒有使用過rxjs,而且我也是一般的新手,所以我有時會遇到一些困難,找到正確的方法去做一些特定的事情。
我現在面臨一個問題。我必須將Array<Observable<T>>轉換爲Observable<Array<T>>
我會嘗試用一個例子來解釋一下:
- 我有一個Observable,這給了我的UsersObservable<Array<User>>
名單 - 該User -class具有功能getPosts返回一個Observable<Array<Post>>
- 我需要將Observable<Array<User>>映射到Observable<Array<Post>>以評估onNext函數中的所有PostRxJs陣列可觀察陣列

我可以從Observable<Array<User>>使用
map((result : Array<User>) => result.map((user : User) => user.getPosts()))
ANS容易映射到Observable<Array<Observable<Array<Post>>>>我可以變平的Array<Array<Post>>Array<Post>
但是我只是找不到正確的方法將Observable<Array<Observable<Array<Post>>>>映射到Observable<Array<Array<Post>>>
到目前爲止,我使用combineLatest功能與flatMap一起。
對我來說,它似乎工作,我使用的編輯器(Atom編輯器)沒有顯示任何錯誤。但是現在我使用Netbeans,它顯示我在這段代碼中有錯誤。還使用「tsc」編譯代碼會導致錯誤。
的是這樣的:

Argument of type '(result: Post[]) => void' is not assignable to parameter of type 'NextObserver<[Observable<Post>]> | ErrorObserver<[Observable<Post>]> | CompletionObserver<[...'. 
Type '(result: Post[]) => void' is not assignable to type '(value: [Observable<Post>]) => void'. 

所以我的問題是:
我如何 「扁平化」 的ObservablesArrayArray

+0

getPosts方法對應什麼?它是否加載特定用戶的帖子? –

回答

22

flatMap運營商允許這樣做。我不完全明白你想做些什麼,但我會盡力提供一個答案......

如果你想加載所有

getPostsPerUser() { 
    return this.http.get('/users') 
    .map(res => res.json()) 
    .flatMap((result : Array<User>) => { 
     return Observable.forkJoin(
     result.map((user : User) => user.getPosts()); 
    }); 
} 

Observable.forkJoin讓你等待所有觀測到有收到數據。

上面的代碼假定user.getPosts()返回一個可觀察......

有了這個,你將收到帖子的數組的數組:

this.getPostsPerUser().subscribe(result => { 
    var postsUser1 = result[0]; 
    var postsUser2 = result[1]; 
    (...) 
}); 
+1

是的'getPosts()'返回'Observable >'。所以我想這就是我正在尋找的。我會盡快嘗試,並讓你知道它是否工作。謝謝 – Springrbua

+0

完美地工作。我只是用'forkJoin'替換'combineLatest'。非常感謝! – Springrbua

3

您可以使用功能上rxjs方法適用你想,像這樣:

const source1 = Rx.Observable.interval(100) 
 
    .map(function (i) { return 'First: ' + i; }); 
 

 
const source2 = Rx.Observable.interval(150) 
 
    .map(function (i) { return 'Second: ' + i; }); 
 

 
const observablesArray = [source1, source2]; 
 

 
const sources = Rx.Observable.combineLatest 
 
.apply(this, observablesArray).take(4) 
 

 
// or 
 

 
const sources = Rx.Observable 
 
       .combineLatest(...observablesArray) 
 
       .take(4) 
 

 
sources.subscribe(
 
    (response) => { 
 
    console.log(response); 
 
    } 
 
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.min.js"></script>

+0

我想這應該工作,但我現在堅持'forkJoin'。 – Springrbua