IT story

BehaviorSubject와 Observable?

hot-time 2020. 2. 9. 19:26
반응형

BehaviorSubject와 Observable?


나는 각도 RxJs 패턴으로 찾고 있어요와 나는 사이의 차이 이해하지 못하는 BehaviorSubject와를 Observable.

내 이해에서 a BehaviorSubject는 시간이 지남에 따라 변경 될 수있는 값입니다 (구독 할 수 있으며 구독자는 업데이트 된 결과를받을 수 있음). 이것은의 동일한 목적으로 보인다 Observable.

언제 Observablevs 를 사용 BehaviorSubject하시겠습니까? BehaviorSubject오버 를 사용 Observable하거나 그 반대로 사용하면 이점이 있습니까?


BehaviorSubject 는 주제 유형이며 주제는 특수한 유형의 관찰 가능하므로 다른 관찰 가능과 같은 메시지를 구독 할 수 있습니다. BehaviorSubject의 고유 한 기능은 다음과 같습니다.

  • 구독을받지 못한 경우에도 구독시 항상 값을 반환해야하므로 초기 값이 필요합니다. next()
  • 구독하면 주제의 마지막 값을 리턴합니다. 일반 옵저버 블은onnext
  • 언제든지 getValue()메소드를 사용하여 관찰 할 수없는 코드로 주제의 마지막 값을 검색 할 수 있습니다 .

관찰 가능한 대상과 비교 한 대상의 고유 한 특징은 다음과 같습니다.

  • 옵저버 블일뿐만 아니라 옵저버이므로 서브 스크립 션에 추가하여 주제에 값을 보낼 수도 있습니다.

또한의 asObservable()메소드를 사용하여 동작 주제에서 관찰 가능 항목을 얻을 수 있습니다 BehaviorSubject.

Observable 은 Generic이고 BehaviorSubjectBehaviorSubject는 특정 품질을 가진 Observable이므로 기술적으로 Observable의 하위 유형입니다.

BehaviorSubject를 사용한 예 :

// Behavior Subject

// a is an initial value. if there is a subscription 
// after this, it would get "a" value immediately
let bSubject = new BehaviorSubject("a"); 

bSubject.next("b");

bSubject.subscribe(value => {
  console.log("Subscription got", value); // Subscription got b, 
                                          // ^ This would not happen 
                                          // for a generic observable 
                                          // or generic subject by default
});

bSubject.next("c"); // Subscription got c
bSubject.next("d"); // Subscription got d

규칙적인 주제를 가진 예 2 :

// Regular Subject

let subject = new Subject(); 

subject.next("b");

subject.subscribe(value => {
  console.log("Subscription got", value); // Subscription wont get 
                                          // anything at this point
});

subject.next("c"); // Subscription got c
subject.next("d"); // Subscription got d

관측은 모두 만들 수 있습니다 SubjectBehaviorSubject사용 subject.asObservable().

유일한 차이점은 next()메소드를 사용하여 관찰 가능 값으로 값을 보낼 수 없다는 것입니다.

Angular 서비스에서는 BehaviorSubject구성 요소 및 동작 주체가 구성 요소 가이 데이터에 가입 한 이후 새로운 업데이트가 없어도 서비스를 소비하는 구성 요소가 마지막으로 업데이트 된 데이터를 수신하기 전에 각도 서비스가 종종 초기화되기 때문에 데이터 서비스에 사용하려고합니다.


관찰 가능 : 관찰자마다 다른 결과

하나의 매우 중요한 차이점. Observable은 함수일 뿐이므로 상태가 없으므로 모든 새로운 Observer에 대해 Observable 작성 코드를 반복해서 실행합니다. 결과는 다음과 같습니다.

코드는 각 관찰자에 대해 실행됩니다. HTTP 호출 인 경우 각 관찰자에 대해 호출됩니다.

이로 인해 주요 버그와 비효율이 발생합니다

BehaviorSubject (또는 Subject)는 관찰자 세부 정보를 저장하고 코드를 한 번만 실행하며 결과를 모든 관찰자에게 제공합니다.

전의:

JSBin : http://jsbin.com/qowulet/edit?js, 콘솔

// --- Observable ---
let randomNumGenerator1 = Rx.Observable.create(observer => {
   observer.next(Math.random());
});

let observer1 = randomNumGenerator1
      .subscribe(num => console.log('observer 1: '+ num));

let observer2 = randomNumGenerator1
      .subscribe(num => console.log('observer 2: '+ num));


// ------ BehaviorSubject/ Subject

let randomNumGenerator2 = new Rx.BehaviorSubject(0);
randomNumGenerator2.next(Math.random());

let observer1Subject = randomNumGenerator2
      .subscribe(num=> console.log('observer subject 1: '+ num));
      
let observer2Subject = randomNumGenerator2
      .subscribe(num=> console.log('observer subject 2: '+ num));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.3/Rx.min.js"></script>

출력 :

"observer 1: 0.7184075243594013"
"observer 2: 0.41271850211336103"
"observer subject 1: 0.8034263165479893"
"observer subject 2: 0.8034263165479893"

Observable.create각 관찰자에 대해 서로 다른 출력을 사용하는 방법을 관찰 하지만 BehaviorSubject모든 관찰자에 대해 동일한 출력을 제공했습니다. 이것은 중요하다.


다른 차이점이 요약되어 있습니다.

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃         Observable                  ┃     BehaviorSubject/Subject         ┃      
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ 
│ Is just a function, no state        │ Has state. Stores data in memory    │
├─────────────────────────────────────┼─────────────────────────────────────┤
│ Code run for each observer          │ Same code run                       │
│                                     │ only once for all observers         │
├─────────────────────────────────────┼─────────────────────────────────────┤
│ Creates only Observable             │Can create and also listen Observable│
│ ( data producer alone )             │ ( data producer and consumer )      │
├─────────────────────────────────────┼─────────────────────────────────────┤
│ Usage: Simple Observable with only  │ Usage:                              │
│ one Obeserver.                      │ * Store data and modify frequently  │
│                                     │ * Multiple observers listen to data │
│                                     │ * Proxy between Observable  and     │
│                                     │   Observer                          │
└─────────────────────────────────────┴─────────────────────────────────────┘

관찰 대상대상 모두 관찰 가능하므로 관찰자가 추적 할 수 있습니다. 그러나 둘 다 독특한 특성을 가지고 있습니다. 또한 총 3 가지 유형의 주제가 있으며 각각의 주제에는 고유 한 특징이 있습니다. 그들 각각을 이해하려고 노력하십시오.

stackblitz 에서 실제 예제를 찾을 수 있습니다 . (실제 출력을 보려면 콘솔을 확인해야합니다)

여기에 이미지 설명을 입력하십시오

Observables

차갑습니다. 최소한 하나의 관찰자가 있으면 코드가 실행됩니다.

데이터 사본 생성 : Observable은 각 관찰자에 대한 데이터 사본을 생성합니다.

단방향 : 관찰자는 관찰 가능 (원점 / 마스터)에 값을 할당 할 수 없습니다.

Subject

그들은 뜨겁다 : 관찰자가없는 경우에도 코드가 실행되고 가치가 방송됩니다.

데이터 공유 : 모든 관찰자간에 동일한 데이터가 공유됩니다.

양방향 : 옵저버는 옵저버 블 (원점 / 마스터)에 값을 할당 할 수 있습니다.

주제를 사용하는 경우 관찰자를 작성하기 전에 브로드 캐스팅되는 모든 값을 놓치게됩니다. 여기에 Replay Subject 가 온다

ReplaySubject

그들은 뜨겁다 : 관찰자가없는 경우에도 코드가 실행되고 가치가 방송됩니다.

데이터 공유 : 모든 관찰자간에 동일한 데이터가 공유됩니다.

양방향 : 옵저버는 옵저버 블 (원점 / 마스터)에 값을 할당 할 수 있습니다. ...을 더한

메시지 스트림 재생 : 재생 제목을 구독 할 때 브로드 캐스트 된 모든 메시지가 수신됩니다.

주제 및 재생 주제에서는 초기 값을 관찰 가능으로 설정할 수 없습니다. 여기에 행동 주제가 온다

BehaviorSubject

그들은 뜨겁다 : 관찰자가없는 경우에도 코드가 실행되고 가치가 방송됩니다.

데이터 공유 : 모든 관찰자간에 동일한 데이터가 공유됩니다.

양방향 : 옵저버는 옵저버 블 (원점 / 마스터)에 값을 할당 할 수 있습니다. ...을 더한

메시지 스트림 재생 : 재생 제목을 구독 할 때 브로드 캐스트 된 모든 메시지가 수신됩니다.

초기 값을 설정할 수 있습니다 : 관측 값을 기본값으로 초기화 할 수 있습니다.


Observable 객체는 푸시 기반 컬렉션을 나타냅니다.

Observer 및 Observable 인터페이스는 관찰자 디자인 패턴이라고도하는 푸시 기반 알림에 대한 일반화 된 메커니즘을 제공합니다. Observable 객체는 알림을 보내는 객체 (제공자)를 나타냅니다. Observer 객체는 객체를받는 클래스 (관찰자)를 나타냅니다.

Subject 클래스는 Observable과 Observer를 모두 상속합니다. 이는 Observable과 Observable입니다. 주제를 사용하여 모든 관찰자를 구독 한 다음 주제를 백엔드 데이터 소스에 구독 할 수 있습니다.

var subject = new Rx.Subject();

var subscription = subject.subscribe(
    function (x) { console.log('onNext: ' + x); },
    function (e) { console.log('onError: ' + e.message); },
    function () { console.log('onCompleted'); });

subject.onNext(1);
// => onNext: 1

subject.onNext(2);
// => onNext: 2

subject.onCompleted();
// => onCompleted

subscription.dispose();

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md 에 대한 추가 정보


예제에서 볼 수없는 한 가지는 asObservable을 통해 BehaviorSubject를 Observable로 캐스팅하면 구독시 마지막 값을 반환하는 동작을 상속한다는 것입니다.

라이브러리가 종종 필드를 관찰 가능하게 표시하므로 (즉, Angular2의 ActivatedRoute의 매개 변수) 장면 뒤에서 Subject 또는 BehaviorSubject를 사용할 수 있으므로 까다로운 비트입니다. 그들이 사용하는 것은 가입 행위에 영향을 미칩니다.

여기를 참조하십시오 http://jsbin.com/ziquxapubo/edit?html,js,console

let A = new Rx.Subject();
let B = new Rx.BehaviorSubject(0);

A.next(1);
B.next(1);

A.asObservable().subscribe(n => console.log('A', n));
B.asObservable().subscribe(n => console.log('B', n));

A.next(2);
B.next(2);

관찰은 반면 만 가입 할 수 있습니다 피사체가 모두 게시하고 구독 당신을 수 있습니다.

따라서 주제를 사용하면 서비스 를 게시자 및 구독자 모두로 사용할 수 있습니다 .

현재로서는 실력이 좋지 Observable않으므로의 예만 공유하겠습니다 Subject.

Angular CLI 예제로 더 잘 이해합시다 . 아래 명령을 실행하십시오 :

npm install -g @angular/cli

ng new angular2-subject

cd angular2-subject

ng serve

내용을 다음 app.component.html으로 바꾸십시오 .

<div *ngIf="message">
  {{message}}
</div>

<app-home>
</app-home>

명령 ng g c components/home실행하여 홈 구성 요소를 생성하십시오. 내용을 다음 home.component.html으로 바꾸십시오 .

<input type="text" placeholder="Enter message" #message>
<button type="button" (click)="setMessage(message)" >Send message</button>

#message여기에 지역 변수가 있습니다. 의 클래스에 속성 message: string; 추가하십시오 app.component.ts.

이 명령을 실행하십시오 ng g s service/message. 에 서비스가 생성됩니다 src\app\service\message.service.ts. 이 서비스를 앱에 제공하십시오 .

로 가져 Subject옵니다 MessageService. 주제도 추가하십시오. 최종 코드는 다음과 같습니다.

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class MessageService {

  public message = new Subject<string>();

  setMessage(value: string) {
    this.message.next(value); //it is publishing this value to all the subscribers that have already subscribed to this message
  }
}

이제이 서비스를 삽입 home.component.ts하고 인스턴스를 생성자에게 전달하십시오. 이 작업 app.component.ts도 수행하십시오. #message서비스 함수에 값을 전달하려면이 서비스 인스턴스를 사용하십시오 setMessage.

import { Component } from '@angular/core';
import { MessageService } from '../../service/message.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent {

  constructor(public messageService:MessageService) { }

  setMessage(event) {
    console.log(event.value);
    this.messageService.setMessage(event.value);
  }
}

내부 app.component.ts에서 다음을 구독 및 구독 취소 (메모리 누수 방지)합니다 Subject.

import { Component, OnDestroy } from '@angular/core';
import { MessageService } from './service/message.service';
import { Subscription } from 'rxjs/Subscription';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {

  message: string;
  subscription: Subscription;

  constructor(public messageService: MessageService) { }

  ngOnInit() {
    this.subscription = this.messageService.message.subscribe(
      (message) => {
        this.message = message;
      }
    );
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

그게 다야.

지금, 임의의 값을 입력 내부 #messagehome.component.html에 출력한다 {{message}}안쪽app.component.html


app.component.ts

behaviourService.setName("behaviour");

behaviour.service.ts

private name = new BehaviorSubject("");
getName = this.name.asObservable();`

constructor() {}

setName(data) {
  this.name.next(data);
}

custom.component.ts

behaviourService.subscribe(response=>{
  console.log(response);    //output: behaviour
});

BehaviorSubjectObservable : RxJS에는 옵저버와 옵저버 블이 있으며 Rxjs는 데이터 스트림과 함께 사용할 여러 클래스를 제공하며 그 중 하나는 BehaviorSubject입니다.

Observables : Observables는 시간이 지남에 따라 여러 값의 게으른 모음입니다.

BehaviorSubject : 초기 값이 필요하고 현재 값을 새로운 가입자에게 내 보냅니다.

 // RxJS v6+
import { BehaviorSubject } from 'rxjs';

const subject = new BehaviorSubject(123);

//two new subscribers will get initial value => output: 123, 123
subject.subscribe(console.log);
subject.subscribe(console.log);

//two subscribers will get new value => output: 456, 456
subject.next(456);

//new subscriber will get latest value (456) => output: 456
subject.subscribe(console.log);

//all three subscribers will get new value => output: 789, 789, 789
subject.next(789);

// output: 123, 123, 456, 456, 456, 789, 789, 789

참고 URL : https://stackoverflow.com/questions/39494058/behaviorsubject-vs-observable



반응형