如何从里面有Observable订阅的函数返回值?

时间:2022-12-07 20:57:58

I dont know how to extract value from Observable to be returned by function in which Observable is present. I need just a value from it to be returned, nothing else.

我不知道如何从Observable中提取值,以便由Observable存在的函数返回。我只需要返回一个值即可返回,没有别的。

Current version which works

当前版本有效

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

I need this to work, function to return value, and then:

我需要这个工作,函数返回值,然后:

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

What am I doing wrong here?

我在这做错了什么?

5 个解决方案

#1


16  

I realize that this Question was quite a while ago and you surely have a proper solution by now, but for anyone looking for this I would suggest solving it with a Promise to keep the async pattern. A more verbose version would be creating a new Promise:

我意识到这个问题已经有一段时间了,你现在肯定有一个合适的解决方案,但对于任何寻找这个问题的人,我建议用Promise解决它以保持异步模式。一个更详细的版本将创建一个新的Promise:

function getValueFromObservable() {
    return new Promise(resolve=>{
        this.store
         .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);
         })
    }
}

On the receiving end you will then have "wait" for the promise to resolve with something like this:

在接收端,您将“等待”承诺以这样的方式解决:

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

A slimmer solution would be using RxJS' .toPromise() instead:

一个更纤薄的解决方案是使用RxJS'。toPromise()代替:

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

The receiving side stays the same as above of course. Hope that helps!

接收方当然保持与上述相同。希望有所帮助!

#2


13  

This is not exactly correct idea of using Observable

这使用Observable并不完全正确

In the component you have to declare class member which will hold an object (something you are going to use in your component)

在组件中,您必须声明将保存对象的类成员(您将在组件中使用的东西)

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

Then a Service will be returning you an Observable:

然后服务将返回一个Observable:

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

Component should prepare itself to be able to retrieve a value from it:

组件应该准备好能够从中检索值:

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

You have to assign a value from an Observable to a variable:

您必须将Observable中的值赋给变量:

And your template will be consuming variable name:

并且您的模板将使用变量名称:

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

Another way of using Observable is through async pipe http://briantroncone.com/?p=623

使用Observable的另一种方法是通过异步管道http://briantroncone.com/?p=623

Note: If it's not what you are asking, please update your question with more details

注意:如果不是您要求的,请更新您的问题并提供更多详细信息

#3


8  

If you want to pre-subscribe to the same Observable which will be returned, just use

如果要预先订阅将返回的相同Observable,请使用

.do():

。做():

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

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

#4


2  

Observable values can be retrieved from any locations. The source sequence is first pushed onto a special observer that is able to emit elsewhere. This is achieved with the Subject class from the Reactive Extensions (RxJS).

可以从任何位置检索可观察值。源序列首先被推送到能够在其他地方发射的特殊观察者。这是通过Reactive Extensions(RxJS)中的Subject类实现的。

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

Store value onto the observer.

将值存储在观察者身上。

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

To retrieve the value from elsewhere, subscribe to the observer like so:

要从其他地方检索值,请订阅观察者,如下所示:

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

Subjects are both Observables and Observers. There are other Subject types such as BehaviourSubject and ReplaySubject for other usage scenarios.

受试者既是可观察者又是观察者。对于其他使用场景,还有其他主题类型,例如BehaviourSubject和ReplaySubject。

Don't forget to import RxJS.

不要忘记导入RxJS。

var Rx = require('rxjs');

#5


0  

For example this is my html template:

例如,这是我的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>

This is the field that binded with template from my Component:

这是与我的Component中的模板绑定的字段:

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

I fetch genres of films from server dynamically. In order do communicate with server I have created FilmService

我动态地从服务器获取电影类型。为了与服务器进行通信,我创建了FilmService

This is the method which communicate server:

这是与服务器通信的方法:

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

Why this method returns Observable<Genre[]> not something like Genre[]?

为什么这个方法返回Observable 不像Genre []?

JavaScript is async and it does not wait for a method to return value after an expensive process. With expensive I mean a process that take a time to return value. Like fetching data from server. So you have to return reference of Observable and subscribe it.

JavaScript是异步的,它不会等待一个方法在昂贵的进程后返回值。昂贵我的意思是一个需要时间来回报价值的过程。就像从服务器获取数据一样。所以你必须返回Observable的引用并订阅它。

For example in my Component :

例如在我的组件中:

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

#1


16  

I realize that this Question was quite a while ago and you surely have a proper solution by now, but for anyone looking for this I would suggest solving it with a Promise to keep the async pattern. A more verbose version would be creating a new Promise:

我意识到这个问题已经有一段时间了,你现在肯定有一个合适的解决方案,但对于任何寻找这个问题的人,我建议用Promise解决它以保持异步模式。一个更详细的版本将创建一个新的Promise:

function getValueFromObservable() {
    return new Promise(resolve=>{
        this.store
         .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);
         })
    }
}

On the receiving end you will then have "wait" for the promise to resolve with something like this:

在接收端,您将“等待”承诺以这样的方式解决:

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

A slimmer solution would be using RxJS' .toPromise() instead:

一个更纤薄的解决方案是使用RxJS'。toPromise()代替:

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

The receiving side stays the same as above of course. Hope that helps!

接收方当然保持与上述相同。希望有所帮助!

#2


13  

This is not exactly correct idea of using Observable

这使用Observable并不完全正确

In the component you have to declare class member which will hold an object (something you are going to use in your component)

在组件中,您必须声明将保存对象的类成员(您将在组件中使用的东西)

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

Then a Service will be returning you an Observable:

然后服务将返回一个Observable:

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

Component should prepare itself to be able to retrieve a value from it:

组件应该准备好能够从中检索值:

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

You have to assign a value from an Observable to a variable:

您必须将Observable中的值赋给变量:

And your template will be consuming variable name:

并且您的模板将使用变量名称:

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

Another way of using Observable is through async pipe http://briantroncone.com/?p=623

使用Observable的另一种方法是通过异步管道http://briantroncone.com/?p=623

Note: If it's not what you are asking, please update your question with more details

注意:如果不是您要求的,请更新您的问题并提供更多详细信息

#3


8  

If you want to pre-subscribe to the same Observable which will be returned, just use

如果要预先订阅将返回的相同Observable,请使用

.do():

。做():

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

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

#4


2  

Observable values can be retrieved from any locations. The source sequence is first pushed onto a special observer that is able to emit elsewhere. This is achieved with the Subject class from the Reactive Extensions (RxJS).

可以从任何位置检索可观察值。源序列首先被推送到能够在其他地方发射的特殊观察者。这是通过Reactive Extensions(RxJS)中的Subject类实现的。

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

Store value onto the observer.

将值存储在观察者身上。

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

To retrieve the value from elsewhere, subscribe to the observer like so:

要从其他地方检索值,请订阅观察者,如下所示:

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

Subjects are both Observables and Observers. There are other Subject types such as BehaviourSubject and ReplaySubject for other usage scenarios.

受试者既是可观察者又是观察者。对于其他使用场景,还有其他主题类型,例如BehaviourSubject和ReplaySubject。

Don't forget to import RxJS.

不要忘记导入RxJS。

var Rx = require('rxjs');

#5


0  

For example this is my html template:

例如,这是我的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>

This is the field that binded with template from my Component:

这是与我的Component中的模板绑定的字段:

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

I fetch genres of films from server dynamically. In order do communicate with server I have created FilmService

我动态地从服务器获取电影类型。为了与服务器进行通信,我创建了FilmService

This is the method which communicate server:

这是与服务器通信的方法:

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

Why this method returns Observable<Genre[]> not something like Genre[]?

为什么这个方法返回Observable 不像Genre []?

JavaScript is async and it does not wait for a method to return value after an expensive process. With expensive I mean a process that take a time to return value. Like fetching data from server. So you have to return reference of Observable and subscribe it.

JavaScript是异步的,它不会等待一个方法在昂贵的进程后返回值。昂贵我的意思是一个需要时间来回报价值的过程。就像从服务器获取数据一样。所以你必须返回Observable的引用并订阅它。

For example in my Component :

例如在我的组件中:

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