BehaviorSubject와 Observable?
나는 각도 RxJs 패턴으로 찾고 있어요와 나는 사이의 차이 이해하지 못하는 BehaviorSubject
와를 Observable
.
내 이해에서 a BehaviorSubject
는 시간이 지남에 따라 변경 될 수있는 값입니다 (구독 할 수 있으며 구독자는 업데이트 된 결과를받을 수 있음). 이것은의 동일한 목적으로 보인다 Observable
.
언제 Observable
vs 를 사용 BehaviorSubject
하시겠습니까? BehaviorSubject
오버 를 사용 Observable
하거나 그 반대로 사용하면 이점이 있습니까?
BehaviorSubject 는 주제 유형이며 주제는 특수한 유형의 관찰 가능하므로 다른 관찰 가능과 같은 메시지를 구독 할 수 있습니다. BehaviorSubject의 고유 한 기능은 다음과 같습니다.
- 구독을받지 못한 경우에도 구독시 항상 값을 반환해야하므로 초기 값이 필요합니다.
next()
- 구독하면 주제의 마지막 값을 리턴합니다. 일반 옵저버 블은
onnext
- 언제든지
getValue()
메소드를 사용하여 관찰 할 수없는 코드로 주제의 마지막 값을 검색 할 수 있습니다 .
관찰 가능한 대상과 비교 한 대상의 고유 한 특징은 다음과 같습니다.
- 옵저버 블일뿐만 아니라 옵저버이므로 서브 스크립 션에 추가하여 주제에 값을 보낼 수도 있습니다.
또한의 asObservable()
메소드를 사용하여 동작 주제에서 관찰 가능 항목을 얻을 수 있습니다 BehaviorSubject
.
Observable 은 Generic이고 BehaviorSubject
BehaviorSubject는 특정 품질을 가진 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
관측은 모두 만들 수 있습니다 Subject
및 BehaviorSubject
사용 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();
}
}
그게 다야.
지금, 임의의 값을 입력 내부 #message
로 home.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
});
BehaviorSubject 와 Observable : 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
'IT story' 카테고리의 다른 글
Java 클래스 파일을 어떻게 "디 컴파일"합니까? (0) | 2020.02.09 |
---|---|
추상 클래스를 인스턴스화 할 수 있습니까? (0) | 2020.02.09 |
PHP에서 유용한 오류 메시지를 얻는 방법은 무엇입니까? (0) | 2020.02.09 |
Git을 사용할 때“오류 : 잘못된 색인 – 치명적 : 색인 파일 손상”을 해결하는 방법 (0) | 2020.02.09 |
Eclipse / Java 코드 완료가 작동하지 않습니다 (0) | 2020.02.09 |