2017-08-19 36 views
1

私は、各オブジェクトを別々に非同期メソッドに渡す必要のあるオブジェクトの配列を持っています(プロキシで処理された後、Observable.fromPromise(...)経由でObservableに変換されます)単一のオブジェクトがいつでも渡され、プロセスがオブジェクトをデータベースに保存している場合に、同じメソッドが使用されるため、方法が必要です)。例えば、これはオブジェクトの配列である:RxJS配列を観測可能にして配列の普通のオブジェクトに戻す

[ 
    { 
    "name": "John", 
    ... 
    }, 
    { 
    "name": "Anna", 
    ... 
    }, 
    { 
    "name": "Joe",, 
    ... 
    }, 
    { 
    "name": "Alexandra", 
    ... 
    }, 
    ... 
] 

今は、データベースにオブジェクトを挿入する挿入whichと呼ばれるメソッドを有します。 storeデータベースインスタンスのメソッドは、新しく作成されたIDを返します。終わりに、最初のオブジェクトがコピーされ、その新しいIDでマッピングされた:これは私は、単一のオブジェクトを挿入する場合に適しています

insert(user: User): Observable<User> { 
    return Observable.fromPromise(this.database.store(user)).map(
    id => { 
     let storedUser = Object.assign({}, user); 
     storedUser.id = id; 
     return storedUser; 
    } 
); 
} 

。しかし、私は単一の挿入のメソッドを呼び出すだけの複数のオブジェクトを挿入するためのサポートを追加したいと思います。現在、これは私が持っているものですが、それは動作しません:予想通り

insertAll(users: User[]): Observable<User[]> { 
    return Observable.forkJoin(
    users.map(user => this.insert(user)) 
); 
} 

insertAll方法は、ユーザーが挿入される(または何か他のもののユーザーとデータベースを埋め)が、私は任意の応答を得ることはありませんそれから戻ってくる。私は起きていることをデバッグしていて、forkJoinが最初にマップされたユーザーからの応答を得ているようですが、他は無視されます。 insertAllへのサブスクリプションは何もしません。insertAllにキャッチするか、insertAllにサブスクライブする2番目のパラメータを使用してもエラーはありません。

だから私は(insertAllで)観察可能でそのフォームのユーザーとバック新しいオブジェクトの配列を放出するソリューションを探しています:

[ 
    { 
    "id": 1, 
    "name": "John", 
    ... 
    }, 
    { 
    "id": 2, 
    "name": "Anna", 
    ... 
    }, 
    { 
    "id": 3, 
    "name": "Joe",, 
    ... 
    }, 
    { 
    "id": 4, 
    "name": "Alexandra", 
    ... 
    }, 
    ... 
] 

私が指している任意の提案のために非常に幸せになります正しい方向。前もって感謝します!

+2

は、明らかなエラーが表示できません:その場合は、あなたは、Rxは1つだけの同時リクエストを送信するためにconcatMapmergeMapを置き換えることができます。最初の約束だけが解決しているようです。データベースが複数の並行した約束をサポートしていますか?約束と 'Promise.all'だけでそれを試すとどうなりますか?(また、最初のコードスニペットでは、 'storedUser'を作成しますが、' storedUser'の代わりに 'user'を返します。) – cartant

+0

幸運なことに、お約束のおかげで、私が今修正したこの例では、タイプミスがありました。 – user1257255

答えて

2

配列から観測可能に変換するにはRx.Observable.from(array)を使用できます。

observableからarrayに変換するには、obs.toArray()を使用してください。これは配列のオブザーバブルを返すので、引き出すにはまだ.subscribe(arr => ...)が必要であることに注意してください。

あなたのコードはforkJoinとなります。は正しく表示されます。あなたがfromを試してみたいんなら、このようなコードを記述します。これを行う方法のような

insertAll(users: User[]): Observable<User[]> { 
    return Observable.from(users) 
    .mergeMap(user => this.insert(user)) 
    .toArray() 
); 
} 

別のよりRXは、彼らが完了して値を発するようになり、そしてforkJoinまたはtoArrayのようにそれらのすべてを待たないだろうそうです。私達はちょうど前の例からtoArrayを省略することができ、我々はそれを得た:

insertAll(users: User[]): Observable<User> { 
    return Observable.from(users) 
    .mergeMap(user => this.insert(user)) 
); 
} 

@cartantが述べたように、問題は、それはあなたのデータベースが複数の接続をサポートしていないかもしれない、Rxのではないかもしれません。

insertAll(users: User[]): Observable<User[]> { 
    return Observable.from(users) 
    .concatMap(user => this.insert(user)) 
    .toArray() // still optional 
); 
} 
+0

ありがとう! 'forkJoin'を' from'に変更し、 'mergeMap' +' toArray'が期待通りに機能し始めました。 – user1257255