簡體   English   中英

RxJs 數組的 Observable 到 Observable 的數組

[英]RxJs Array of Observable to Observable of Array

對於在 TypeScript 中使用 Angular2 編寫的 Web 應用程序,我需要使用 RxJs Observable s。
由於我以前從未使用過 rxjs,而且我對反應式編程一般來說還是新手,因此有時我很難找到正確的方法來做一些特定的事情。
我現在面臨一個問題。 我必須將Array<Observable<T>>轉換為Observable<Array<T>>
我會試着用一個例子來解釋它:

  • 我有一個Observable ,它給了我一個Users列表( Observable<Array<User>>
  • User類有一個函數getPosts返回一個Observable<Array<Post>>
  • 我需要將Observable<Array<User>>映射到Observable<Array<Post>>以評估onNext函數內的所有Post

我可以輕松地從Observable<Array<User>>映射到Observable<Array<Observable<Array<Post>>>>使用
map((result : Array<User>) => result.map((user : User) => user.getPosts()))
我可以將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'.  

所以我的問題是:
如何將Observables Array “展平”為Array

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允許您等待所有 observable 接收到數據。

上面的代碼假設user.getPosts()返回一個 observable...

有了這個,您將收到一系列帖子:

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

您可以在所需的 rxjs 方法上使用 apply 函數,如下所示:

 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 you can write it without "apply" this way: 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>

在這個 observables 數組上使用 forkJoin,那么它將是一個 observable 數組。

這是一些使用 rxjs@6.3.3 的示例代碼

import { of, forkJoin} from 'rxjs';
import { Observable } from 'rxjs'

const source:Array<Observable<String>> = [of('A'), of('B'), of('C') ];

forkJoin(source).subscribe( (x)=> console.log(x))

https://arrayofobservablesexamp.stackblitz.io

使用toArray()

range(0, 7).pipe(
  concatMap(v => of(`day_${v}`)),
  toArray() // here
).subscribe(a => {
  console.log(a); // ['day_0', 'day_1', ... 'day_6']
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM