2016-08-22 1 views
4

먼저 긴 제목을 보내 주시면 죄송합니다.rxjs/Observable : 첫 번째 스트림을 얻은 후에 한 번 함수 실행 (연속 관찰 가능)

내가 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. 한 번만 실행됩니까?

답변

3

동일한 데이터 스트림을 여러 번 구독하십시오. 또한 구독 기능은 connect()에 전화 할 때까지 호출되지 않습니다. 우리가 person.items.publish().connect() 설탕입니다 person.items.share()를 사용한 경우 , 그것은 바로 요청을 할 것이며, 우리의 응용 프로그램은-경쟁 조건으로 인해 버그가있을 수 있습니다. 모든 대

zip() 대기 항목을 방출 관찰 통과 배열로 한꺼번에 그 품목을 방출한다. 이 항목이 첫 번째 항목에서만 발생하기를 원하므로 take(1)입니다. 목록의 초기 값을 얻을 것이다 중포 기지 목록에 import 'rxjs/add/operator/first'.first() 연산자를 사용

+0

이것은 내가 의도 한대로 작동합니다 (아직 어떻게 작동하는지 알지만). 감사! 그래도 '출판물'이 나오기 전에 '...'이 무엇인지 물어볼 수 있을까요? – shinglesmingles

+0

'스프레드 연산자'라고합니다. 함수 (... [a, b, c])는 함수 (a, b, c)와 동일하지만 여러 요소와 함께 작동합니다. – j2L4e

+0

는 '발행물'을'connectables'에 이름을 바꿔서 무슨 일이 일어나고 있는지 잘 반영합니다. – j2L4e

0

그것은 당신이 달성하려고하는 것을 완전히 아니다. 첫 번째 사람을받은 후에 "myIntendedFunction"을 호출하려고한다는 것을 알았습니다. 관찰 가능 항목을 여러 번 구독 할 수 있으며 (구독 순서가 중요 함) 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

죄송합니다. 나는 관찰 대상 목록 (1 인당 1)을 구독하고 ** 모든 ** 구독이 첫 번째 값을 반환 한 후에이 기능을 실행하려고합니다. 이 사실을 더 잘 반영하기 위해 원래 게시물을 수정했습니다. – shinglesmingles

0

. 이 연산자가 없으면 함수가 여러 번 호출되고 브라우저가 중단 될 수 있습니다. .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(); 
     }); 
    }) 
관련 문제