2016-08-22 16 views
4

まず、長いタイトルを残して申し訳ありません。rxjs/Observable:最初のストリームを取得した後に関数を1回実行する(連続観測可能)

私はangularfire2からforEachとの連続ストリームの配列に加入しようとしていますが、私は、データの最初のセットが入って来たことを確認した後、私はまた、関数を実行したいと思います:

this.people.forEach((person) => { 
    person.items = this.database.list('/items' + person.key); 
    person.items.subscribe((data) => {person.itemsList = data}); 
}); 

myIntendedFunction(); 

配置する方法はありますmyIntendedFunction()よう:

  1. それdataの最初のストリームは、各personのために受信された後に実行され、
  2. これは1回だけ実行されますか?

答えて

3

同じデータストリームを複数回購読する。 connect()に電話するまで、サブスクリプション機能は呼び出されません。 person.items.publish().connect()の砂糖であるperson.items.share()を使用した場合、リクエストがすぐに行われ、競争条件のためにアプリケーションがバグになる可能性があります。

zip()は、経過観察可能なすべてのアイテムを放出するのを待機し、それらのアイテムを一度に配列として放出します。これは最初の項目でのみ発生するようにしたいので、ただtake(1)です。

+0

これは私が意図したとおりに動作します(ただし、まだ動作していますが)。ありがとう!しかし、出版物の前に '...'が何のためにあるのか尋ねることはできますか? – shinglesmingles

+0

これは「スプレッド演算子」と呼ばれています。関数(... [a、b、c])は関数(a、b、c)と同じですが、任意の数の要素で動作します。 – j2L4e

+0

は、 'publables'を' connectables'にリネームして、何が起こっているのかをよりよく反映させました – j2L4e

0

これはあなたが達成しようとしているものではありません。 私はあなたが最初の人が受け取られた後に "myIntendedFunction"を呼び出そうとしていることを理解していました。 あなたはobservableを複数回購読することができます(サブスクリプション注文の問題)、first()演算子を使用して最初の値を取ってからサブスクライブします。

const connectables: ConnectableObservable<any>[] = []; 

this.people.forEach(person => { 
    person.items = this.database.list('/items' + person.key); 
    const connectable = person.items.publish(); 
    connectables.push(connectable); 
    connectable.subscribe((data) => {person.itemsList = data}); 
}); 

Observable.zip(...connectables).take(1).subscribe(myIntendedFunction); 

connectables.forEach(c => c.connect()); 

は何ここで起こることはこれです:publish()の効果は基本的にあなたができることです。これは、あなたが最初の要求が二度起こるしたくない場合は、達成するためにはもう少し複雑です

this.people.subscribe((person) => { 
    person.items= this.database.list('/items'); 
    person.items.subscribe((data) => {person.itemsList = data}); 
}); 

this.people.first().subscribe(myIntendedFunction); 
+0

ご迷惑をおかけして申し訳ありません。私はobservables(1人につき1)のリストを購読し、**すべての**サブスクリプションが最初の値を返した後にその関数を実行しようとしています。私はこれをよりよく反映するためにオリジナルの投稿を修正しました。 – shinglesmingles

0

firebaseリストの.first()演算子をimport 'rxjs/add/operator/first'とすると、リストの初期値が得られます。この演算子がなければ、関数は複数回呼び出され、ブラウザがクラッシュする可能性があります。 .toPromise()演算子を import 'rxjs/add/operator/toPromise'とすると、得られたリストを観測可能なものに変換できます。 .then()を使用して、お約束を使用して目的の機能を実行することができます。

this.forEach.person((people) => { 
     person.items = this.database.list('/items' + person.key); 
     person.items 
      .first() 
      .toPromise() 
      .then(() => { 
       myIntendedFunction(); 
     }); 
    }) 
関連する問題