programing

구독하지 않고 Observable에서 현재 값 가져오기(단 한 번만 값 받기)

linuxpc 2023. 9. 13. 22:22
반응형

구독하지 않고 Observable에서 현재 값 가져오기(단 한 번만 값 받기)

Observable을 구독하지 않고 현재 값을 가져오려면 어떻게 해야 합니까?저는 단지 현재의 값을 한 번만 원하며 들어오는 새로운 값을 원하진 않습니다.

빠른 답변:

...현재의 가치를 한 번만 원해요. 새로운 가치가 들어오는 것이 아니라...

계속 사용하게 됩니다.subscribe, 하지만 같이pipe(take(1))따라서 하나의 가치를 제공합니다.

예를 들면myObs$.pipe(take(1)).subscribe(value => alert(value));

참고 항목:또는 간의 비교


긴 답변:

인 에서 을 은 인 은 을 에서 subscribe()

(또는 Angular를 사용하는 경우 비동기 파이프)

BehaviorSubject확실히 자리가 있고, RxJS를 시작할때는 자주 그랬었습니다.bs.value()가치를 얻기 위해서 입니다.RxJS 스트림이 전체 애플리케이션에 전파됨에 따라(그것이 바로 당신이 원하는 것입니다!), 이렇게 하는 것은 점점 더 어려워질 것입니다.종종 당신은 실제로 보게 될 것입니다..asObservable()누군가가 사용하지 못하도록 기본 유형을 '숨기는' 데 사용됩니다..value()- 처음에는 비열하게 보이겠지만, 시간이 지남에 따라 왜 이런 일이 이루어지는지를 알게 될 것입니다.게다가 당신은 곧 당신이 필요로 하는 것이 아닌 것에 대한 가치를 필요로 할 것입니다.BehaviorSubject그렇게 만들 방법이 없을 겁니다

다시 원래 질문으로 돌아갑니다.히를서기를 이'지면ae면pyuot'지fy히를'를a이BehaviorSubject.

항상 사용하는 것이 더 나은 접근 방식입니다.subscribe가치를 얻기 위해서 입니다.

obs$.pipe(take(1)).subscribe(value => { ....... })

오어

obs$.pipe(first()).subscribe(value => { ....... })

는 ㅇㅇㅇfirst()스트림이 이미 완료된 경우 오류가 발생합니다.take(1)스트림이 완료되었거나 즉시 사용 가능한 값이 없는 경우에는 관측 가능한 값을 내보내지 않습니다.

참고: 이 방법은 행동 주제를 사용하는 경우에도 더 나은 방법으로 간주됩니다.

그러나 위의 코드를 사용해 보면 관측치의 '값'이 구독 함수의 닫힘 내부에 '걸려' 있게 되고 현재 범위에서 필요할 수 있습니다.이 문제를 해결할 수 있는 한 가지 방법은 다음과 같습니다.

const obsValue = undefined;
const sub = obs$.pipe(take(1)).subscribe(value => obsValue = value);
sub.unsubscribe();

// we will only have a value here if it was IMMEDIATELY available
alert(obsValue);

위의 구독 호출은 값을 기다리지 않습니다.당장 이용할 수 있는 것이 없으면 구독 취소 기능은 절대 호출되지 않을 것이고, 저는 '나중에 나타나지 않도록' 일부러 거기에 가입 취소 전화를 걸었습니다.

따라서 이는 매우 서툴러 보일 뿐만 아니라 http 호출의 결과 값과 같이 즉시 사용할 수 없는 것에는 작동하지 않지만 실제로 동작 주체(또는 업스트림에 있고 동작 주체*로 알려진 것)와 함께 작동할 수 있습니다.combineLatest합니다.BehaviorSubject값).그리고 절대로 가서는 안돼요.(obs$ as BehaviorSubject) - 으악!

이 이전의 예는 여전히 일반적으로 나쁜 관행으로 여겨집니다. 엉망진창입니다.값이 즉시 사용 가능한지 확인하고 사용 가능하지 않은지 확인하려면 이전 코드 스타일만 수행합니다.

최선의 접근법

모든 것을 가능한 한 오랫동안 관찰 가능하게 유지하고, 가치가 꼭 필요할 때만 구독할 수 있다면, 그리고 제가 위에서 하고 있는 일인 포함 범위에 가치를 '추출'하려고 하지 않는 것이 훨씬 더 좋을 것입니다.

예를 들어 동물원이 문을 연다면 동물에 대한 보고서를 만들고 싶다고 합시다.이 된'고다할지도다할지도feu을'u은de't이k'고된t'ezooOpen$다음과 같이:

나쁜방법

zooOpen$: Observable<boolean> = of(true);    // is the zoo open today?
bear$: Observable<string> = of('Beary');
lion$: Observable<string> = of('Liony');

runZooReport() {

   // we want to know if zoo is open!
   // this uses the approach described above

   const zooOpen: boolean = undefined;
   const sub = this.zooOpen$.subscribe(open => zooOpen = open);
   sub.unsubscribe();

   // 'zooOpen' is just a regular boolean now
   if (zooOpen) 
   {
      // now take the animals, combine them and subscribe to it
      combineLatest(this.bear$, this.lion$).subscribe(([bear, lion]) => {

          alert('Welcome to the zoo! Today we have a bear called ' + bear + ' and a lion called ' + lion); 
      });
   }
   else 
   {
      alert('Sorry zoo is closed today!');
   }
}

그럼 왜 이렇게 나쁜 거지?

  • 에 ㅇㅇzooOpen$웹 서비스에서 왔습니까?앞의 예는 어떻게 작동할 것입니까?서버의 속도가 얼마나 빠른지는 중요하지 않습니다. 만약 당신이 위의 코드로 값을 얻을 수 없을 것입니다.zooOpen$observable!p!
  • 이 보고서를 이 기능을 '외부'로 사용하려면 어떻게 해야 합니까?은제을다y을 잠갔습니다.alert이 방법으로.보고서를 다른 곳에서 사용해야 한다면 이것을 복제해야 할 것입니다!

굿웨이

자신의 기능에 있는 가치에 접근하려고 하지 말고, 새로운 Observable을 만들고 그것에 가입하지도 않는 기능을 고려해 보십시오!

대신 '외부'에서 소비할 수 있는 새로운 관측치를 반환합니다.

모든 것을 관찰 가능한 상태로 유지하고 사용함으로써switchMap다른 관측치의 출처가 될 수 있는 새로운 관측치를 만들 수 있습니다.

getZooReport() {

  return this.zooOpen$.pipe(switchMap(zooOpen => {

     if (zooOpen) {

         return combineLatest(this.bear$, this.lion$).pipe(map(([bear, lion] => {

                 // this is inside 'map' so return a regular string
                 return "Welcome to the zoo! Today we have a bear called ' + bear + ' and a lion called ' + lion";
              }
          );
      }
      else {

         // this is inside 'switchMap' so *must* return an observable
         return of('Sorry the zoo is closed today!');
      }

   });
 }

의 내용은 새로운 관측 자료를 생성하므로 다른 곳에서 실행할 수 있으며 원한다면 파이프를 더 많이 사용할 수 있습니다.

 const zooReport$ = this.getZooReport();
 zooReport$.pipe(take(1)).subscribe(report => {
    alert('Todays report: ' + report);
 });

 // or take it and put it into a new pipe
 const zooReportUpperCase$ = zooReport$.pipe(map(report => report.toUpperCase()));

다음 사항에 유의합니다.

  • 꼭 필요할 때까지 구독하지 않습니다. 이 경우에는 기능 밖입니다.
  • 은 ① '주행'입니다.zooOpen$그리고 그것을 사용하는.switchMap로 '이 관측치는 로인른환로 다'에서 반환되는 입니다.getZooReport().
  • ㅇㅇㅇzooOpen$하고 첫 면든째서다시고e다ner서든면stns째s을고tswitchMap. ㅜㅜㅜㅜㅜㅜswitchMap그것에 관해 더 많이 알고 싶습니다.
  • : 안의 : 의 switchMap새 관측치를 반환해야 합니다.빨리 만들 수 있습니다.of('hello')- 또는 다음과 같은 관측 가능한 다른 것을 반환합니다.combineLatest.
  • 마찬가지로:map일반 문자열만 반환해야 합니다.

저는 필요할 때까지 구독하지 말라는 마음의 메모를 시작하자마자 갑자기 훨씬 더 생산적이고 유연하며 깨끗하고 유지보수 가능한 코드를 쓰기 시작했습니다.

메모: 에 이 하면 Angular에 대해 하나의 Angular에 대한 보고서 없이 .subscribe| async '할 교장선생님의 입니다.pipe. 이것은 실제로 '해야 할 때까지 구독하지 마세요' 교장 선생님을 보여주는 좋은 예입니다.

// in your angular .ts file for a component
const zooReport$ = this.getZooReport();

템플릿에 다음을 입력합니다.

<pre> {{ zooReport$ | async }} </pre>

여기에서 내 답변도 참조하십시오.

https://stackoverflow.com/a/54209999/16940

또한 혼동을 피하기 위해 위에 언급하지 않음:

  • tap() 때때로 '관측 가능한 값을 얻는' 데 유용할 수 있습니다.만약 당신이 그 연산자에 익숙하지 않다면 그것을 읽어보세요.RxJS는 '파이프'와 a를 사용합니다.tap()연산자는 파이프를 두드려 무엇이 있는지 확인하는 방법입니다.

.toPromise() / 비동기 사용

https://benlesh.medium.com/rxjs-observable-interop-with-promises-and-async-await-bebb05306875 에서 '비동기/슬롯과 함께 약속에 사용()'을 참조하여 마지막 관찰 가능한 값을 약속으로 표시합니다.


각도 신호 포함! (각도 16+)

앵글 16은 새로운 시그널 기능의 프리뷰를 선보였습니다.기능이 완전하지는 않지만 구성 요소에서 신호 사용을 이미 시작할 수 있습니다.디자인 목표 중 하나는 바로 이 '고통점'을 고치는 것입니다.

와 함께customer = toSignal(customer$, { requireSync: true })한 값이 Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ 값으로 접근할 수 있습니다.customer()위에 설명된 일반 보일러 플레이트 없이.Angular는 이를 달성하기 위해 생성된 관측치에 대한 구독 취소를 자동으로 처리합니다.

이에 대한 의견:

  • 에 로 신호 ()값을 얻는 것은 항상 동기적이므로 관측 자료에 값이 없으면 위에서 설명한 것과 같은 문제가 발생합니다.그 점이랴.{ requireSync: true }에 대해 설명합니다(자세한 정보는 API 문서에서 확인 - 변경될 수 있음).
  • 저는 기존 관측 가능한 값이 필요한 시점에 새로운 신호를 만들자고 제안하는 것입니다.그건 좀 무의미해요!이 방법은 신호를 일부 또는 전부 사용하도록 구성 요소를 업데이트하는 경우에만 유용합니다.
  • 시그널 API는 최종적인 것이 아니므로 블로그에서 최신 정보를 확인해보세요.

Behavior Subject를 사용해야 합니다.

  • BehaviorSubject는 마지막 출판물만 기억한다는 점을 제외하고는 ReplaySubject와 비슷합니다.
  • BehaviorSubject에는 기본값 T도 입력해야 합니다.이는 모든 가입자가 (이미 완료되지 않은 경우) 값을 즉시 받게 된다는 것을 의미합니다.

관찰자가 최근에 발표한 값을 제공합니다.

는 BehaviorSubject를 합니다.getter이라는 재산value가장 최근의 가치를 전달할 수 있습니다.


스택블리츠

  • 이 예에서는 콘솔에 'a' 값을 씁니다.

//Declare a Subject, you'll need to provide a default value.
const subject: BehaviorSubject<string> = new BehaviorSubject("a");

사용방법:

console.log(subject.value); // will print the current value

제목을 숨기고 값만 노출합니다.

BehaviorSubject를 숨기고 그 가치만 드러내고자 하는 경우, 예를 들어 서비스에서 이런 게터를 사용할 수 있습니다.

export class YourService {
  private subject = new BehaviorSubject('random');

  public get subjectValue() {
    return this.subject.value;
  }
}
const value = await this.observableMethod().toPromise();

ToPromise()가 어느 시점부터 더 이상 사용되지 않기 때문에 다음을 수행할 수 있는 새로운 rxjs 방법이 방법은 다음과 같습니다.

let value = await lastValueFrom(someObservable);

아니면

let value = await firstValueFrom(someObservable);

무언가가 이미 안에 들어있는지 확신할 수 없는 경우 다음을 사용할 수 있습니다.

let value = await lastValueFrom(someObservable, {defaultValue: "some value"})

https://indepth.dev/graphics/1287/graphicsjs-promise-in-being-comparation

이것이 당신이 찾고 있는 것인지 확실하지 않습니다.아마도 서비스에 그 행동 주제를 적을 것입니다.비공개로 선언하고 설정한 값만 노출합니다.이런 거.

 @Injectable({
   providedIn: 'root'
 })
  export class ConfigService {
    constructor(private bname:BehaviorSubject<String>){
       this.bname = new BehaviorSubject<String>("currentvalue");
    }

    getAsObservable(){
       this.bname.asObservable();
    }
 }

이렇게 하면 외부 사용자는 behaviorSubject에만 가입할 수 있으며 서비스에서 원하는 값을 설정할 수 있습니다.

관측 가능 생성기를 사용하여 모든 유형의 관측 가능한 스트림을 만듭니다.생성자는 관찰자의 subscriber() 메서드가 실행될 때 실행할 구독자 함수를 인수로 사용합니다.가입자 함수는 Observer 개체를 수신하고, Observer의 다음() 메서드에 값을 게시할 수 있습니다.이거 먹어봐요.

@Component({
  selector: 'async-observable-pipe',
  template: '<div><code>observable|async</code>: Time: {{ time | async }} . 
</div>'
})
export class AsyncObservablePipeComponent {
  time = new Observable<string>((observer: Observer<string>) => {
    setInterval(() => observer.next(new Date().toString()), 1000);
  });
}

언급URL : https://stackoverflow.com/questions/37339016/get-current-value-from-observable-without-subscribing-just-want-value-one-time

반응형