itsource

RxJs Subject 또는 Observable의 현재 값을 얻는 방법

mycopycode 2022. 9. 12. 11:49
반응형

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에서 최신 값을 얻는 몇 가지 방법이 있습니다.

  1. 「」를 사용합니다.BehaviorSubject- 근데 사실 구독하고 있어요.처음 구독할 때BehaviorSubject수신한 이전 값 또는 초기화된 값을 동기화하여 전송합니다.
  2. 「」의 ReplaySubject(N): 캐시됩니다.N새로운 서브스크라이버에게 재생합니다.
  3. A.withLatestFrom(B): 이B 가능한 경우A 두 합니다. 이치[a, b].
  4. A.combineLatest(B): 이하여 : 에서 A ★★★★★★★★★★★★★★★★★」BA ★★★★★★★★★★★★★★★★★」B방출합니다. 배열에서 두 값을 모두 제공합니다.
  5. shareReplay(): 를ReplaySubject그러나 오류 발생 시 관찰 가능한를 재시도할 수 있습니다(기본적으로 약속 캐시 동작을 제공합니다).
  6. 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...
  });

이를 실현하는 방법에는 두 가지가 있습니다.

  1. Behavior Subject에는 메서드가 있습니다.getValue()을 사용하다

  2. 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

반응형