No sé cómo extraer valor de Observable para que lo devuelva la función en la que Observable está presente. Necesito solo un valor de él para ser devuelto, nada más.
Versión actual que funciona
function getValueFromObservable() {
this.store.subscribe(
(data:any) => {
console.log(data)
}
)
}
getValueFromObservable()
Necesito que esto funcione, que funcione para devolver el valor, y luego:
function getValueFromObservable() {
this.store.subscribe(
(data:any) => {
return data
}
)
}
console.log(getValueFromObservable())
¿Qué estoy haciendo mal aquí?
typescript
angular
rxjs
rxjs5
Osito de peluche
fuente
fuente
subscribe
Respuestas:
EDITAR: código actualizado para reflejar los cambios realizados en la forma en que funcionan las tuberías en versiones más recientes de RXJS. Todos los operadores (tome en mi ejemplo) ahora están envueltos en el operador pipe ().
Me doy cuenta de que esta pregunta fue hace bastante tiempo y seguramente ya tiene una solución adecuada, pero para cualquiera que busque esto, sugeriría que la resuelva con una promesa de mantener el patrón asíncrono.
Una versión más detallada sería la creación de una nueva promesa:
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); }) }) }
En el extremo receptor, tendrá que "esperar" a que la promesa se resuelva con algo como esto:
getValueFromObservable() .then((data:any)=>{ //... continue with anything depending on "data" after the Promise has resolved })
Una solución más delgada sería usar RxJS '.toPromise () en su lugar:
function getValueFromObservable() { return this.store.pipe(take(1)) .toPromise() }
El lado receptor permanece igual que el anterior, por supuesto.
fuente
getValueFromObservable
función?Esta no es exactamente la idea correcta de usar
Observable
En el componente, debe declarar el miembro de la clase que contendrá un objeto (algo que usará en su componente)
export class MyComponent { name: string = ""; }
Entonces
Service
te devolverá unObservable
:getValueFromObservable():Observable<string> { return this.store.map(res => res.json()); }
Component
debe prepararse para poder recuperar un valor de él:OnInit(){ this.yourServiceName.getValueFromObservable() .subscribe(res => this.name = res.name) }
Tienes que asignar un valor de una
Observable
a una variable:Y su plantilla consumirá la variable
name
:Otra forma de uso
Observable
es medianteasync
tubería http://briantroncone.com/?p=623Nota : Si no es lo que está preguntando, actualice su pregunta con más detalles.
fuente
name
disponible fuera de la devolución de llamada asignándolo a laname
variable del componente . No es posible regresarname
sincrónicamente en su caso.Oninit
así, ¿qué pasa si necesito regresar explícitamente? Mi código de llamada se ve asíthis.actions$.ofType(SearchActions.SEARCH_MULTIPLE_NEW_QUERY).map(toPayload).fnWithMultipleAsyncReturns()
Si desea suscribirse previamente al mismo Observable que se devolverá, solo use
function getValueFromObservable() { return this.store.do( (data:any) => { console.log("Line 1: " +data); } ); } getValueFromObservable().subscribe( (data:any) => { console.log("Line 2: " +data) } );
fuente
.map(data => data)
que hacen lo mismo y luego suscribirlo donde espere el resultadodo
ahora se llamatap
y debe usarlo en una tubería. También tenga en cuenta quetap
toma múltiples parámetros para diferentes controladores comonext
,complete
yerror
.Parece que está buscando un captador de "valor actual" dentro de un observable, cuando emite y después de una emisión.
Subject
yObservable
no tiene tal cosa. Cuando se emite un valor, se pasa a sus suscriptores yObservable
se hace con él.Puede utilizar
BehaviorSubject
que almacena el último valor emitido y lo emite inmediatamente a los nuevos suscriptores.También tiene un
getValue()
método para obtener el valor actual;Otras lecturas:
Comportamiento de RxJS Sujeto
¿Cómo obtener el valor actual del sujeto u observable RxJS?
fuente
Los valores observables se pueden recuperar de cualquier ubicación. La secuencia de origen se envía primero a un observador especial que puede emitir en otro lugar. Esto se logra con la clase Subject de Reactive Extensions (RxJS).
var subject = new Rx.AsyncSubject(); // store-last-value method
Almacene valor en el observador .
subject.next(value); // store value subject.complete(); // publish only when sequence is completed
Para recuperar el valor de otro lugar, suscríbase al observador así:
subject.subscribe({ next: (response) => { //do stuff. The property name "response" references the value } });
Los sujetos son tanto observables como observadores. Hay otros tipos de sujetos como BehaviourSubject y ReplaySubject para otros escenarios de uso.
No olvide importar RxJS.
var Rx = require('rxjs');
fuente
Si bien las respuestas anteriores pueden funcionar de alguna manera, creo que usar BehaviorSubject es la forma correcta si desea continuar usando observables.
Ejemplo:
this.store.subscribe( (data:any) => { myService.myBehaviorSubject.next(data) } )
En el servicio:
let myBehaviorSubject = new BehaviorSubjet(value);
En component.ts:
this.myService.myBehaviorSubject.subscribe(data => this.myData = data)
¡Espero que esto ayude!
fuente
Por ejemplo, esta es mi plantilla 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>
Este es el campo que se enlazó con la plantilla de mi componente:
// Genres of films like action or drama that will populate dropdown list. genres: Genre[];
Busco géneros de películas del servidor de forma dinámica. Para comunicarse con el servidor que he creado
FilmService
Este es el método que comunica el servidor:
fetchGenres(): Observable<Genre[]> { return this.client.get(WebUtils.RESOURCE_HOST_API + 'film' + '/genre') as Observable<Genre[]>; }
¿Por qué este método
Observable<Genre[]>
no devuelve algo comoGenre[]
?JavaScript es
async
y no espera a que un método devuelva valor después de un proceso costoso. Con caro me refiero a un proceso que tarda un tiempo en devolver valor. Como recuperar datos del servidor. Por lo tanto, debe devolver la referencia de Observable y suscribirse.Por ejemplo, en mi componente:
ngOnInit() { this.filmService.fetchGenres().subscribe( val => this.genres = val ); }
fuente
function getValueFromObservable() { this.store.subscribe( (data:any) => { return data } ) } console.log(getValueFromObservable())
En el caso anterior, console.log se ejecuta antes de que se resuelva la promesa, por lo que no se muestra ningún valor, cámbialo a lo siguiente
function getValueFromObservable() { return this.store } getValueFromObservable() .subscribe((data: any) => { // do something here with data console.log(data); });
otra solución es cuando necesita datos dentro de getValueFromObservable para devolver el operador observable y suscribirse a la función.
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); });
fuente
En el mundo de JavaScript de tendencia reactiva, asíncrono, orientado a promesas y de un solo subproceso, se
async/await
encuentra el mejor amigo del programador de estilo imperativo:(async()=>{ const store = of("someValue"); function getValueFromObservable () { return store.toPromise(); } console.log(await getValueFromObservable()) })();
Y en caso de que
store
sea una secuencia de múltiples valores: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); } })();
fuente
from(["someValue","someOtherValue"])
con un observable de su elección que emita más de un valor. Supongo que podría ser más adecuado haberlo usadointerval(1000)
.La forma decente sería devolver el observable de una función y suscribirse a él donde sea necesario, porque los observables son perezosos, comenzarán a emitir valores solo cuando estén suscritos.
Aquí tengo una solución impulsada por eventos más interesante, con la que inicialmente solía jugar. El siguiente ejemplo hace esto usando el módulo " eventos " de nodejs. Puede usarlo con otros marcos donde exista un módulo similar ( Nota : la sintaxis y el estilo pueden cambiar según el módulo utilizado).
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
Es solo un ejemplo para mostrar una idea en la que podemos pasar datos de diferentes lugares mediante el método de emisión y escucha. Esto también se conoce como código controlado por eventos.
fuente