私は次のコードを持っています:
//Loop: For each user ID/Role ID, get the data
userMeta.forEach((businessRole) => {
Observable.forkJoin(
af.database.object('/roles/'+businessRole.$value),
af.database.object('/users/'+businessRole.$key)
).subscribe(
data => {
console.log("Data received");
data[1].role = data[0];
this.users.Push(data[1]);
},
err => console.error(err)
);
forkJoin
を使用して2つのオブザーバブルの結果をサブスクライブしようとしています。
何らかの理由で、「Data received」メッセージは表示されません。
userMeta
変数はconsole.logで正常に見えます:
どうしましたか?
更新:次のコードも何も返しません
let source = Observable.forkJoin(
af.database.object('/roles/'+businessRole.$value),
af.database.object('/users/'+businessRole.$key)
);
let subscription = source.subscribe(
function (x) {
console.log("GOT: " + x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
私が実際にやろうとしているのは、次のコードのパフォーマンスを改善することです。
//Subscription 3: role ID to role Name
af.database.object('/roles/'+businessRole.$value)
.subscribe((roleData) => {
//Subscription 4: Get user info
af.database.object('/users/'+businessRole.$key).subscribe(user => {
forkJoin()
は、すべてのソースObservablesが少なくとも1回発行して完了することを要求します。
この次のデモは期待どおりに完了します。
const source = forkJoin(
from([1,2,3]),
from([9,8,7,6])
).subscribe(
x => console.log('GOT:', x),
err => console.log('Error:', err),
() => console.log('Completed')
);
ライブデモ: https://stackblitz.com/edit/rxjs-urhkni
GOT: 3,6
Completed
2019年1月:RxJS 6用に更新
Angular 2/Angularfire 2を使用して同様の問題が発生しました。具体的には、ユーザーがメールで存在したかどうかを調べていました。1つのケースでは、ユーザーが存在し、1つのオブジェクトの配列を観察可能:他の場合、ユーザーは存在せず、空の配列を受け取りました。
ResultSelectorとsubscribeでforkJoinを使用した場合、resultSelectorもsubscribe関数も実行されませんでした。しかし、私が試したとき
Observable.Zip(
FirebaseListObservable,
FirebaseListObservable,
(...results) => {
return results.map(some code here)
}
).subscribe(res => console.log(res));
セレクターとサブスクライブの両方が機能しました。これは@martinの答えと関係があると思います。定義では、forkJoinがオブザーバブルを完了する必要があるのは、定義により最後の放出を返すためです。オブザーバブルが完全に完了しない場合、lastの放出が発生することはないと思います。
おそらく、アンギュラファイアリストのオブザーバブル(または、あなたの場合はオブジェクトオブザーバブル)は決して完了せず、forkJoinの使用は不可能です。幸いなことに、Zipにはsimilarの動作があり、動作します。Firebaseでデータが変更された場合、forkJoinが最後の応答のみを結合する場合、数回繰り返すことができる点が異なります。
私の場合、1)Zipを使用して、.Zipの実行中にユーザーデータが変更されるとコードが複数回実行される可能性があることを受け入れています。2)最初のデータセットが返された後、Zipを手動で無効にします。 3)Angularfireを捨て、.onceのようなものを使用して直接Firebase apiを試して、forkJoinを完了してトリガーするオブザーバブルを取得できるかどうかを確認します。
私は同様の問題に直面しました:オブザーバブルのリストを動的に作成していましたが、オブザーバブルのリストが空の場合、forkjoin()
は空になっても解決されず、Promise.all()
リスト:
Observable.forkJoin([])
.subscribe(() => console.log('do something here')); // This is never called
私が見つけた回避策は、リストの長さをチェックし、空の場合はこの演算子を使用しないことです。
return jobList.length ? Observable.forkJoin(jobList) : Observable.of([]);
Observer.complete();を追加するだけです。
動作しません:
observer.next(...)
動作します:
observer.next(...);
observer.complete();
それが役に立てば幸い。