본문 바로가기
프로그래밍/Angular

[RxJS / angular] 18. Subject와 BehaviorSubject

by 신나요 2022. 7. 30.

이번 포스트에서는 subject와 observable의 차이를 알아보며 멀티캐스트와 유니캐스트의 정의를 살펴보겠습니다. 마지막에는 subject의 단점을 보안할 수 있는 BehaviorSubject에 대해 알아봅니다.


Subject 란

Subject는 옵저버블이자 옵저버인 특별한 유형의 옵저버블입니다. subject는 아래 코드에서 처럼 new 키워드를 사용해서 생성할 수 있습니다.

생성할 때 제네릭으로 subject가 방출하는 항목의 타입 지정을 위해 타입 인수를 지정합니다. subject는 옵저버 인터페이스를 구현하기 때문에 next 메서드를 호출하여 항목을 방출할 수 있습니다.

그리고 여전히 옵저버블이기 때문에 알림을 수신하고자 하려는 모든 코드에서 subscribe 메서드를 호출할 수 있습니다.

다시 말해 옵저버블이자 옵저버의 역할을 모두 하는 옵저버블이 Subject입니다.


Observable과 Subject의 차이점 (유니캐스트 vs 멀티캐스트)

observable과 subject간의 주요 차이점은 observable은 일반적으로 유니캐스트이고 subject는 멀티캐스트라는점 입니다.

유니캐스트는 1:1로 메시지를 전송하는 방식을 의미합니다. 즉 옵저버블은 대개 단일 구독자에게 알림을 전달합니다. 따라서 구독자가 다수인 경우 각 구독자는 알림을 전달받기 위해 다수의 옵저버블이 필요합니다.

subject는 멀티캐스트입니다. 멀티캐스트는 하나의 메시지가 여러 수신처로 전송하는 것을 의미합니다. 다시 말해 여러 구독자에게 전송됩니다. 여러 가입자가 동일한 방출 항목을 공유합니다. 이러한 특성 덕분에 subject를 사용하면 여러 구독자 간에 작업을 공유할 수 있습니다.

 

아래 코드에서 of 생성자를 사용해서 옵저버블을 생성하고 있습니다. 옵저버블이므로 유니캐스트입니다. 콘솔 출력을 예상해보세요.

첫 번째 구독에서 옵저버블은 항목을 내보내고 각 항목은 옵저버에 의해 처리됩니다. 두 번째 구독은 동일한 항목을 방출하는 새로운 옵저버블을 가져오고 옵저버에 의해 처리됩니다. 마블 다이어그램으로 보면 아래 표현됩니다. 콘솔 출력과 마블 다이어그램을 보면 아래와 같습니다.

 

아래 코드에서는 subject를 생성하고 있습니다. subject이므로 멀티캐스트입니다.

첫 번째 구독에서는 subject가 아직 아무것도 방출하지 않았기 때문에 아무 일도 일어나지 않습니다.

subject가 next를 호출하여 방출하면 구독자는 값이 포함된 알림을 받습니다. 첫 번째 구독자에서 'a'를 받고 콘솔에 출력됩니다.

그런 다음 다른 구독자가 해당 subject를 구독하고 있습니다. 두 번째 구독자는 늦게 구독했기 때문에 첫 번째 방출 값 'a'를 얻지 못할 것입니다.

subject에서 다시 next를 호출해서 'b'를 방출하고 있습니다. subject가 방출되면 모든 구독자는 값이 포함된 알림을 수신하고 방출 값을 처리하게 됩니다. 따라서 첫 번째 구독자와 두 번째 구독자는 방출 값을 전달받게 됩니다. 반복해서 'c'가 방출되고 같은 과정이 일어납니다. 그리고 complete 메서드를 호출하여 subject가 완료되면 각 구독자는 구독 취소되고 subject의 역할은 끝이 납니다. 그러면 더 이상 아이템을 방출할 수 없게 됩니다.

콘솔 출력과 마블 다이어그램은 아래와 같습니다.

 

두 번째 구독자는 값 'a'를 받지 못했습니다. subject로 코드를 짤 때는 구독 전에 발생하는 방출을 놓칠 수 있으므로 방출 시점과 구독 시점에 주의를 기울이는 것이 중요합니다. 이러한 subject의 단점을 보안할 수 있는 것이 Behavior Subject입니다.


Behavior Subject

Behavior Subject는 마지막으로 방출한 값을 버퍼링 하고 있어 마지막 방출 값을 늦게 구독한 구독자에게 방출해 주는 특별한 유형의 Subject입니다.

Behavior Subject를 생성하려면 기본값을 지정해야 합니다. 위 예에서 기본값이 a로 설정하고 있습니다. Behavior Subject는 아직 항목을 방출하지 않은 경우 해당 기본값을 방출합니다. Behavior Subject를 사용하면 늦게 구독하는 문제를 해결할 수 있습니다.

첫 번째 구독에서 기본값 '' 이 구독자에게 방출됩니다. behavior subject가 next를 호출하여 방출하면 모든 구독자는 값이 포함된 알림을 수신하고 처리하게 됩니다. a가 방출되고 첫 번째 구독자는 a를 받게 됩니다. 두 번째 구독자는 늦은 구독자입니다. 하지만 behavior subject가 방출된 값을 버퍼링 하고 있기 때문에 구독과 동시에 'a'값을 얻게 됩니다. 늦게 구독했지만 최근에 방출된 값은 얻을 수 있었습니다. 콘솔 출력을 보면 다음과 같습니다.

 

마블 다이어그램에서 생각해 보면 다음과 같습니다.

behavior subject를 사용하여 구독이 늦었지만 a를 받을 수 있었습니다. 이렇게 Behavior Subject의 특성을 이용하면 subject의 단점을 보안할 수 있습니다.


여기까지 수고하셨습니다. 다음 포스트에서는 subject를 사용하여 액션 스트림을 만들고 데이터를 필터링해보도록 하겠습니다.

댓글