如何返回值的函数有可观察的订阅内?

我不知道如何从 Observer 中提取值,以便通过函数返回,而在函数中,Observer 是存在的。我只需要从它返回一个值,其他什么都不需要。

当前版本可以工作

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

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

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

我做错了什么?

263129 次浏览

这种使用 Observable的想法并不完全正确

在组件中,您必须声明类成员,该类成员将包含一个对象(您将在组件中使用的对象)

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

然后一个 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

注意 : 如果不是你要问的问题,请更新你的问题的更多细节

编辑: 更新代码,以反映 RXJS 最新版本中管道工作方式的变化。现在,所有的运算符(以我的示例为例)都包装到管道()运算符中。

我意识到这个问题已经过去很久了,现在您肯定已经有了一个合适的解决方案,但是对于任何寻找这个问题的人来说,我建议使用一个  来解决它,以保持异步模式。

一个更详细的版本将创造一个新的承诺:

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 的. toPromit ()来代替:

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

当然,接收端保持不变。

可以从任何位置检索可观测值。源序列首先是 被推下去的到一个特殊的 观察者上,该 观察者能够在其他地方发出。这是通过反应扩展(RxJS)中的 科目类别实现的。

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
}
});

主题既是可观察的,也是观察者。还有其他的 主题类型,比如用于其他使用场景的 Behavior ourSubject 和 ReplaySubject。

别忘了导入 RxJS。

var Rx = require('rxjs');

如果你想预订将被返回的同一个可观测数据,只需使用

. do () :

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


getValueFromObservable().subscribe(
(data:any) => {
console.log("Line 2: " +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,它不会等待方法在代价高昂的进程之后返回值。我所说的昂贵是指一个需要时间来返回值的过程。比如从服务器获取数据。因此,您 必须的返回可观察的引用并订阅它。

例如,在我的组件中:

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

问题是,数据是在可观测的内部捕获的,我只需要控制台将其记录下来。我想通过调用它所在的函数从不同的文件返回这个值和 console. log 或者其他东西。

看起来你正在寻找一个“当前值”获取器内观察,当它发射和发射之后。

SubjectObservable没有这样的东西。当发出一个值时,它被传递给它的订阅者,Observable就完成了。

您可以使用 BehaviorSubject,它存储最后发出的值并立即将其发送给新的订阅者。

它还有一个 getValue()方法来获得当前值;

进一步阅读:

RxJS 行为主体

如何得到当前值的 RxJS 主题或观察?

虽然前面的答案可能在某种程度上有效,但是我认为如果您想继续使用可观察对象,那么使用 Behavior orSubject 是正确的方法。

例如:

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

服务范围:

let myBehaviorSubject = new BehaviorSubjet(value);

在组件.ts 中:

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

希望这个能帮上忙!

在单线程、异步、面向承诺、反应趋势的 javascript async/await世界中,命令式程序员最好的朋友是:

(async()=>{


const store = of("someValue");
function getValueFromObservable () {
return store.toPromise();
}
console.log(await getValueFromObservable())


})();

如果 store是一个多值序列:

  const aiFrom = require('ix/asynciterable').from;
(async function() {


const store = from(["someValue","someOtherValue"]);
function getValuesFromObservable () {
return aiFrom(store);
}
for await (let num of getValuesFromObservable()) {
console.log(num);
}
})();
function getValueFromObservable() {
this.store.subscribe(
(data:any) => {
return data
}
)
}
console.log(getValueFromObservable())

在上面的例子中,console. log 在承诺解决之前运行,因此不显示任何值,将其更改为 following

function getValueFromObservable() {
return this.store
}


getValueFromObservable()
.subscribe((data: any) => {
// do something here with data
console.log(data);
});

另一种解决方案是当您需要 getValueFromObserver 内部的数据来返回可观察的使用操作符和订阅函数时。

 function getValueFromObservable() {
return this.store.subscribe((data: any) => {
// do something with data here
console.log(data);
//return again observable.
return of(data);
})
}


getValueFromObservable()
.subscribe((data: any) => {
// do something here with data
console.log(data);
});

比较合适的方法是从函数返回可观测值,并在需要的地方订阅它,因为可观测值是惰性的,它们只有在被订阅时才会开始发出值。

在这里,我有一个更有趣的事件驱动解决方案,我最初使用它。下面的示例通过使用 nodejs 的“ 事件”模块来实现这一点。您可以在存在类似模块的其他框架中使用它(注意: 根据使用的模块,语法和样式可能会发生变化)。

var from =require("rxjs").from;
var map = require("rxjs/operators").map;
var EventEmitter = require("events");


function process(event) {
from([1,2,3]).pipe(
map(val => `The number is:: ${val}`)
).subscribe((data) => {
event.emit("Event1", data); //emit value received in subscribe to the "Event1" listener
});
}


function main() {
class Emitter extends EventEmitter{};
var event = new Emitter(); //creating an event
event.on("Event1", (data)=>{ //listening to the event of name "Event1" and callback to log returned result
console.log(data); //here log, print, play with the data you receive
});
process(event); //pass the event to the function which returns observable.
}


main(); //invoke main function

这只是一个例子,展示了我们可以通过发送和监听的方法从不同的地方传递数据的想法。这也称为事件驱动代码。

从函数返回可观察值。

RxjsFunction.ts

import { Observable } from 'rxjs'


export function getValueFromObservable() {


return new Observable( (obs) => {
obs.next(5);
})
}

Mats

import { getValueFromObservable } from "./rxjsFunction";


getValueFromObservable().subscribe((value) => {
next: console.log(value);
});

我想检查数据是否存储在客户机上,或者是否必须通过 API 调用从服务器获取数据。然后返回一个新的观察者并订阅这个应用程序。第一次从服务器获取数据时,返回 this. allUsers,因为我是在调用 API 并返回数据之后设置这些数据的。

    private _allUsers: EnconUser[] = undefined;
get allUsers(): EnconUser[]
{
return this._allUsers;
}
set allUsers(value: EnconUser[])
{
this.storage.store('allUsers', value);
this._allUsers = value;
}


public getAllUsers() : Observable<EnconUser[]>
{
if (this.allUsers == undefined)
{
return new Observable((obs) => {this.httpClient.get<EnconUser[]>(`http://api/getallusers`).subscribe(data=>{this.allUsers=data; obs.next(data); })});
}
else
{
return new Observable((obs) => {
obs.next(this.allUsers);
});
}
}