RxJs Subject 또는 Observable의 현재 값을 얻는 방법
Angular 2 서비스가 있습니다.
import {Storage} from './storage';
import {Injectable} from 'angular2/core';
import {Subject} from 'rxjs/Subject';
@Injectable()
export class SessionStorage extends Storage {
private _isLoggedInSource = new Subject<boolean>();
isLoggedIn = this._isLoggedInSource.asObservable();
constructor() {
super('session');
}
setIsLoggedIn(value: boolean) {
this.setItem('_isLoggedIn', value, () => {
this._isLoggedInSource.next(value);
});
}
}
모든 것이 잘 작동한다.그러나 구독할 필요가 없는 다른 컴포넌트가 있습니다.isLogged의 현재 값을 취득하기만 하면 됩니다.특정 시점에 들어오게 됩니다.이거 어떻게 해?
A Subject
★★★★★★★★★★★★★★★★★」Observable
현재 값이 없습니다.되면, 그와 「」, 「」, 「」, 「」에 건네집니다.Observable
이제 끝이야.
값을 " " " 를 사용합니다.BehaviorSubject
을 사용하다 BehaviorSubject
는, 해, 새로운합니다.
은 또한 도 가지고 있다.getValue()
현재 값을 가져옵니다.
Observable/Subject 값을 "아웃"하려면 Subscribe를 사용해야 합니다.
★★★★★★★★★를 사용하고 있는 경우는getValue()
선언적 패러다임에서 뭔가 필수적으로 행동하고 있는 거야그것은 탈출구로서 존재하지만, 99.9%는 사용하지 않는 것이 좋습니다.라는 흥미로운 점이 몇 가지 있다.getValue()
다음 작업을 수행합니다.서브스크라이브가 해제된 경우 에러가 발생하며 서브스크라이브가 에러 등으로 정지된 경우 값을 얻을 수 없습니다.하지만, 다시 말하지만, 그것은 드문 상황을 위한 탈출구입니다.
"Rx-y" 방식으로 Subject 또는 Observatable에서 최신 값을 얻는 몇 가지 방법이 있습니다.
- 「」를 사용합니다.
BehaviorSubject
- 근데 사실 구독하고 있어요.처음 구독할 때BehaviorSubject
수신한 이전 값 또는 초기화된 값을 동기화하여 전송합니다. - 「」의
ReplaySubject(N)
: 캐시됩니다.N
새로운 서브스크라이버에게 재생합니다. A.withLatestFrom(B)
: 이B
가능한 경우A
두 합니다. 이치[a, b]
.A.combineLatest(B)
: 이하여 : 에서A
★★★★★★★★★★★★★★★★★」B
A
★★★★★★★★★★★★★★★★★」B
방출합니다. 배열에서 두 값을 모두 제공합니다.shareReplay()
: 를ReplaySubject
그러나 오류 발생 시 관찰 가능한를 재시도할 수 있습니다(기본적으로 약속 캐시 동작을 제공합니다).publishReplay()
,publishBehavior(initialValue)
,multicast(subject: BehaviorSubject | ReplaySubject)
: : : : , , , , , , , ,를 활용하는 기타 연산자BehaviorSubject
★★★★★★★★★★★★★★★★★」ReplaySubject
같은 것의 다른 플레이버에서는 기본적으로 서브젝트를 통해 모든 알림을 전송함으로써 관찰 가능한 소스를 멀티캐스트합니다.요.connect()
서브스크라이브 할 수 있습니다.
서브젝트 값이 도착한 후 후발 구독자가 서브젝트를 구독하는 비슷한 상황이 있었습니다.
이 경우 Behavior Subject와 비슷한 Replay Subject가 매력적으로 작동합니다.자세한 설명에 대한 링크는 다음과 같습니다.
const observable = of('response')
function hasValue(value: any) {
return value !== null && value !== undefined;
}
function getValue<T>(observable: Observable<T>): Promise<T> {
return observable
.pipe(
filter(hasValue),
first()
)
.toPromise();
}
const result = await getValue(observable)
// Do the logic with the result
// .................
// .................
// .................
구현 방법에 대한 전문은 여기에서 확인할 수 있습니다.https://www.imkrish.com/blog/development/simple-way-get-value-from-observable
처음에는 Subject의 현재 값을 가진 후 Subject에 가입하여 변경을 들어야 하는 하위 구성 요소에서도 동일한 문제가 발생했습니다.다음과 같은 컴포넌트가 액세스 할 수 있도록 서비스의 현재 값을 유지합니다.
import {Storage} from './storage';
import {Injectable} from 'angular2/core';
import {Subject} from 'rxjs/Subject';
@Injectable()
export class SessionStorage extends Storage {
isLoggedIn: boolean;
private _isLoggedInSource = new Subject<boolean>();
isLoggedIn = this._isLoggedInSource.asObservable();
constructor() {
super('session');
this.currIsLoggedIn = false;
}
setIsLoggedIn(value: boolean) {
this.setItem('_isLoggedIn', value, () => {
this._isLoggedInSource.next(value);
});
this.isLoggedIn = value;
}
}
현재 값을 필요로 하는 컴포넌트는 서비스를 통해 액세스할 수 있습니다.즉, 다음과 같습니다.
sessionStorage.isLoggedIn
이것이 올바른 프랙티스인지 아닌지는 잘 모르겠습니다.
비슷하게 보이는 답변이 다운 투표되었다.하지만 제한된 경우에 제가 제안하는 것을 정당화할 수 있다고 생각합니다.
관측치에 현재 값이 없는 것은 사실이지만 즉시 사용할 수 있는 값이 있는 경우가 많습니다.예를 들어, 레덕스 / 플럭스 / 아키타 저장소의 경우 여러 관측치를 기반으로 중앙 저장소에서 데이터를 요청할 수 있으며 일반적으로 이 값은 즉시 사용할 수 있습니다.
는, 「 」, 「 」의 입니다.subscribe
값은 즉시 반환됩니다.
예를 들어, 서비스를 요청했는데, 완료 후 매장으로부터 다음 정보를 얻을 수 없는 최신 정보를 얻으려고 합니다.
이렇게 할 수 있습니다(그리고 가능한 한 '파이프 안'에 물건을 보관해야 합니다).
serviceCallResponse$.pipe(withLatestFrom(store$.select(x => x.customer)))
.subscribe(([ serviceCallResponse, customer] => {
// we have serviceCallResponse and customer
});
이 문제의 문제는 세컨더리 관측 가능 값이 방출될 때까지 차단된다는 것입니다. 이 값은 잠재적으로 절대 방출되지 않을 수 있습니다.
저는 최근에 값이 즉시 사용 가능한 경우에만 관측 가능한 값을 평가할 필요가 있다는 것을 깨달았고, 더 중요한 것은 값이 사용 가능하지 않은지 탐지할 수 있어야 한다는 것입니다.결국 이렇게 됐어요.
serviceCallResponse$.pipe()
.subscribe(serviceCallResponse => {
// immediately try to subscribe to get the 'available' value
// note: immediately unsubscribe afterward to 'cancel' if needed
let customer = undefined;
// whatever the secondary observable is
const secondary$ = store$.select(x => x.customer);
// subscribe to it, and assign to closure scope
sub = secondary$.pipe(take(1)).subscribe(_customer => customer = _customer);
sub.unsubscribe();
// if there's a delay or customer isn't available the value won't have been set before we get here
if (customer === undefined)
{
// handle, or ignore as needed
return throwError('Customer was not immediately available');
}
});
의 모든 「」를 사용하고 것에 해 주세요.subscribe
(@Ben이 설명한 바와 같이) 값을 가져옵니다.「」를 ..value
부동산이 있어도BehaviorSubject
.
과잉 살상으로 들릴지 모르지만, 이것은 관찰 가능한 유형을 유지하고 보일러 플레이트를 줄이기 위한 또 다른 "가능한" 해결책일 뿐입니다.
언제든지 확장 getter를 생성하여 관찰 가능한 현재 값을 가져올 수 있습니다.
이를 위해서는 다음 명령어를 확장해야 합니다.Observable<T>
의 인터페이스global.d.ts
선언 파일을 입력합니다.그런 다음 확장 getter를 에 구현합니다.observable.extension.ts
마지막으로 타이핑과 확장 파일을 모두 애플리케이션에 포함시킵니다.
이 StackOverflow Answer를 참조하여 Angular 응용 프로그램에 확장을 포함하는 방법을 확인할 수 있습니다.
// global.d.ts
declare module 'rxjs' {
interface Observable<T> {
/**
* _Extension Method_ - Returns current value of an Observable.
* Value is retrieved using _first()_ operator to avoid the need to unsubscribe.
*/
value: Observable<T>;
}
}
// observable.extension.ts
Object.defineProperty(Observable.prototype, 'value', {
get <T>(this: Observable<T>): Observable<T> {
return this.pipe(
filter(value => value !== null && value !== undefined),
first());
},
});
// using the extension getter example
this.myObservable$.value
.subscribe(value => {
// whatever code you need...
});
이를 실현하는 방법에는 두 가지가 있습니다.
Behavior Subject에는 메서드가 있습니다.
getValue()
을 사용하다Behavior Subject에 직접 가입할 수 있으며 가입된 값을 클래스 멤버, 필드 또는 속성에 전달할 수 있습니다.
두 가지 방법 모두 추천하지 않습니다.
첫 번째 접근 방식에서는 언제든지 값을 얻을 수 있는 편리한 방법입니다. 이 방법을 해당 시점의 현재 스냅샷이라고 할 수 있습니다.문제는 코드에 레이스 조건을 도입할 수 있다는 것입니다.디버깅이 어려운 다양한 장소와 타이밍에 이 메서드를 호출할 수 있습니다.
두 번째 접근법은 대부분의 개발자가 서브스크립션 시 원시 값을 원할 때 사용하는 방법입니다. 서브스크립션을 추적할 수 있습니다.또한 메모리 누수를 피하기 위해 서브스크립션을 정확히 언제 취소해야 하는지 추적할 수 있습니다.또한 이를 변수에 바인드하고 다른 인터페이스 방법이 없을 경우 이 방법을 사용할 수도 있습니다.
사용 사례를 다시 한 번 살펴보면 어디에 사용합니까?예를 들어 API를 호출할 때 사용자가 로그인하고 있는지 여부를 확인하려면 다른 관찰 가능한 API를 조합할 수 있습니다.
const data$ = apiRequestCall$().pipe(
// Latest snapshot from BehaviorSubject.
withLatestFrom(isLoggedIn),
// Allow call only if logged in.
filter(([request, loggedIn]) => loggedIn)
// Do something else..
);
「UI」의 「UI」의 「에 직접 접속할 수 .data$ | async
각진 경우
구독을 만든 후 첫 번째 내보낸 항목을 가져간 후 파기할 수 있습니다.다음 예제에서 pipe()는 Observatable을 입력으로 사용하고 출력으로 다른 Observatable을 반환하는 함수이며 첫 번째 Observatable은 수정하지 않습니다.
「 」로 된 샘플.Angular 8.1.0
「」"rxjs": "6.5.3"
,"rxjs-observable": "0.0.7"
ngOnInit() {
...
// If loading with previously saved value
if (this.controlValue) {
// Take says once you have 1, then close the subscription
this.selectList.pipe(take(1)).subscribe(x => {
let opt = x.find(y => y.value === this.controlValue);
this.updateValue(opt);
});
}
}
관측 가능과는 별도로 마지막으로 방출된 값을 저장할 수 있습니다.그리고 필요할 때 읽어보세요.
let lastValue: number;
const subscription = new Service().start();
subscription
.subscribe((data) => {
lastValue = data;
}
);
은 ""를 사용하는 입니다.Behaviur Subject
하다
var sub = new rxjs.BehaviorSubject([0, 1])
sub.next([2, 3])
setTimeout(() => {sub.next([4, 5])}, 1500)
sub.subscribe(a => console.log(a)) //2, 3 (current value) -> wait 2 sec -> 4, 5
언급URL : https://stackoverflow.com/questions/37089977/how-to-get-current-value-of-rxjs-subject-or-observable
'itsource' 카테고리의 다른 글
C#에 null margeing 연산자(--)와 동등한 Java가 있습니까? (0) | 2022.09.12 |
---|---|
클릭으로 PHP 기능 실행 (0) | 2022.09.12 |
MySQL/PHP를 사용하여 필드에 now()를 사용하여 현재 날짜/시간을 삽입합니다. (0) | 2022.09.12 |
셀 값을 날짜로 설정하고 기본 Excel 날짜 형식을 적용하려면 어떻게 해야 합니까? (0) | 2022.09.12 |
JavaScript를 사용하여 드롭다운 목록에서 선택한 값 가져오기 (0) | 2022.09.12 |