[typescript] Observable 구독이있는 함수에서 값을 반환하는 방법은 무엇입니까?

Observable이있는 함수에 의해 반환되도록 Observable에서 값을 추출하는 방법을 모르겠습니다. 반환 할 값만 있으면됩니다.

작동하는 현재 버전

function getValueFromObservable() {
    this.store.subscribe(
        (data:any) => {
            console.log(data)
        }
    )
}
getValueFromObservable()

이 기능이 작동하고 값을 반환하는 기능이 필요합니다.

function getValueFromObservable() {
    this.store.subscribe(
        (data:any) => {
            return data
        }
    )
}
console.log(getValueFromObservable())

내가 여기서 뭘 잘못하고 있니?



답변

편집 : RXJS의 최신 버전에서 파이프가 작동하는 방식에 대한 변경 사항을 반영하기 위해 코드를 업데이트했습니다. 이제 모든 연산자 (예제 참조)가 pipe () 연산자로 래핑됩니다.

나는이 질문이 꽤 오래 전이고 당신은 확실히 적절한 해결책을 가지고 있음을 알고 있지만 이것을 찾는 사람에게는 비동기 패턴을 유지하겠다는 약속으로 해결하는 것이 좋습니다.

더 자세한 버전은 새로운 Promise를 만드는 것입니다.

function getValueFromObservable() {
    return new Promise(resolve=>{
        this.store.pipe(
           take(1) //useful if you need the data once and don't want to manually cancel the subscription again
         )
         .subscribe(
            (data:any) => {
                console.log(data);
                resolve(data);
         })
    })
}

받는 쪽에서 다음과 같이 해결하겠다는 약속을 “대기”하게됩니다.

getValueFromObservable()
   .then((data:any)=>{
   //... continue with anything depending on "data" after the Promise has resolved
})

더 얇은 솔루션은 대신 RxJS의 .toPromise ()를 사용하는 것입니다.

function getValueFromObservable() {
    return this.store.pipe(take(1))
       .toPromise()
}

수신 측은 물론 위와 동일하게 유지됩니다.


답변

이것은 사용에 대한 정확한 아이디어가 아닙니다. Observable

컴포넌트에서 객체 (컴포넌트에서 사용할 것)를 보유 할 클래스 멤버를 선언해야합니다.

export class MyComponent {
  name: string = "";
}

그러면 a Service가 다음을 반환합니다 Observable.

getValueFromObservable():Observable<string> {
    return this.store.map(res => res.json());
}

Component 그것에서 값을 검색 할 수 있도록 준비해야합니다.

OnInit(){
  this.yourServiceName.getValueFromObservable()
    .subscribe(res => this.name = res.name)
}

의 값을 Observable변수 에 할당해야 합니다.

그리고 템플릿은 변수를 소비합니다 name.

<div> {{ name }} </div>

사용하는 또 다른 방법 Observable을 통해서이다 async파이프 http://briantroncone.com/?p=623

참고 : 요청한 내용이 아닌 경우 자세한 내용으로 질문을 업데이트하세요.


답변

반환 될 동일한 Observable을 미리 구독하려면 다음을 사용하십시오.

.하다():

function getValueFromObservable() {
    return this.store.do(
        (data:any) => {
            console.log("Line 1: " +data);
        }
    );
}

getValueFromObservable().subscribe(
        (data:any) => {
            console.log("Line 2: " +data)
        }
    );


답변

문제는 데이터가 옵저버 블 내부에서 캡처되고 콘솔 로그 만 가능하다는 것입니다. 그 값과 console.log 또는 그것이 상주하는 함수를 호출하여 다른 파일에서 무엇이든 반환하고 싶습니다.

옵저버 블 내부에서 “현재 값”getter를 찾고있는 것 같습니다.

Subject그리고 Observable그런 일이 없습니다. 값이 방출되면 구독자에게 전달되고 값 Observable이 완료됩니다.

BehaviorSubject마지막으로 방출 된 값을 저장하고 새 구독자에게 즉시 방출하는 것을 사용할 수 있습니다 .

또한 getValue()현재 값을 가져 오는 방법 도 있습니다 .

추가 자료 :

RxJS 동작 주제

RxJS Subject 또는 Observable의 현재 값을 얻는 방법은 무엇입니까?


답변

관찰 가능한 값은 모든 위치에서 검색 할 수 있습니다. 소스 시퀀스는 먼저 다른 곳에서 방출 할 수 있는 특수 관찰자에게 푸시 됩니다. 이는 RxJS (Reactive Extensions) 의 주제 클래스 를 통해 수행됩니다.

var subject = new Rx.AsyncSubject();  // store-last-value method

관찰자에게 값을 저장합니다 .

subject.next(value); // store value
subject.complete(); // publish only when sequence is completed

다른 곳에서 값을 검색하려면 다음과 같이 관찰자를 구독하십시오.

subject.subscribe({
  next: (response) => {
      //do stuff. The property name "response" references the value
  }
});

주제는 Observable과 Observer입니다. 다른 사용 시나리오에 대한 BehaviourSubject 및 ReplaySubject와 같은 다른 주제 유형이 있습니다.

RxJS를 가져 오는 것을 잊지 마십시오.

var Rx = require('rxjs');


답변

이전 답변이 패션으로 작동 할 수 있지만 계속해서 Observable을 사용하려면 BehaviorSubject를 사용하는 것이 올바른 방법이라고 생각합니다.

예:

    this.store.subscribe(
        (data:any) => {
            myService.myBehaviorSubject.next(data)
        }
    )

서비스에서 :

let myBehaviorSubject = new BehaviorSubjet(value);

component.ts에서 :

this.myService.myBehaviorSubject.subscribe(data => this.myData = data)

이게 도움이 되길 바란다!


답변

예를 들어 이것은 내 html 템플릿입니다.

<select class="custom-select d-block w-100" id="genre" name="genre"
                  [(ngModel)]="film.genre"
                  #genreInput="ngModel"
                  required>
            <option value="">Choose...</option>
            <option *ngFor="let genre of genres;" [value]="genre.value">{{genre.name}}</option>
          </select>

이것은 내 구성 요소의 템플릿으로 바인딩 된 필드입니다.

  // Genres of films like action or drama that will populate dropdown list.
  genres: Genre[];

서버에서 영화 장르를 동적으로 가져옵니다. 내가 만든 서버와 통신하려면FilmService

이것은 서버와 통신하는 방법입니다.

 fetchGenres(): Observable<Genre[]> {
    return this.client.get(WebUtils.RESOURCE_HOST_API + 'film' + '/genre') as Observable<Genre[]>;
  }

이 메서드가 Observable<Genre[]>다음과 같은 것을 반환 하지 않는 이유는 무엇 Genre[]입니까?

JavaScript는 async값 비싼 프로세스 후 메서드가 값을 반환 할 때까지 기다리지 않습니다. 비싸다는 것은 가치를 반환하는 데 시간이 걸리는 프로세스를 의미합니다. 서버에서 데이터를 가져 오는 것과 같습니다. 따라서 Observable의 참조 반환하고 구독해야합니다.

예를 들어 내 구성 요소에서 :

ngOnInit() {
    this.filmService.fetchGenres().subscribe(
      val => this.genres = val
    );
  }