2016-07-10 4 views
28

Ich weiß nicht, wie man Wert von Observable extrahiert, um von Funktion zurückgegeben werden, in der Observable vorhanden ist. Ich brauche nur einen Wert, um zurückgegeben zu werden, sonst nichts.Wie man Wert von der Funktion zurückgibt, die Observable-Subskription innen hat?

Aktuelle Version, die

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

Ich brauche dies funktioniert, funktionieren zurückzukehren Wert arbeitet, und dann:

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

Was mache ich hier falsch?

+1

Sie einen beobachtbaren zurückkehren sollte/Versprechen und übergeben Sie die Daten über sie, wenn Ihre Observable aufgelöst wird – galvan

+1

Können Sie einen einfachen Code dafür setzen? – Teddy

+4

Was Sie versuchen, ist ein Anti-Pattern: Sie versuchen, eine asynchrone Aufgabe zu "synchronisieren". Das ist nicht die Art, wie Observable funktionieren sollen. Kurz gesagt, in den meisten Fällen sollte eine Funktion, die eine beobachtbare Funktion als Eingabe hat, auch eine beobachtbare - oder nichts zurückgeben. Und wenn Sie etwas mit der Ausgabe tun müssen, abonnieren Sie es. In diesem Fall, wenn Sie console.log die Daten senden möchten, tun Sie es einfach in "subscribe" –

Antwort

7

Dies ist nicht genau richtige Vorstellung von Observable

In der Komponente Sie haben Klassenmitglied zu erklären, die ein Objekt halten werden (etwas, das Sie in Ihrer Komponente verwenden werden)

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

Dann

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

Component sh: ein Service erhalten Sie eine Observable zurückkehren

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

Sie haben einen Wert von einem Observable zu einer Variablen zuzuweisen:

Und Ihre Vorlage wird variabel verbrauchen name:

<div> {{ name }} </div> 
Wert abrufen zu können, von ihm Ould selbst vorbereiten

Ein anderer Weg der Verwendung von Observable ist durch async Rohr http://briantroncone.com/?p=623

Hinweis: Wenn es nicht das, was Sie fragen, aktualisieren Sie bitte Ihre Frage mit mehr Details

+0

Nun, nicht ganz. Das Problem ist, dass Daten innerhalb der Observablen erfasst werden und ich kann sie einfach loggen. Ich möchte diesen Wert und console.log oder was auch immer von einer anderen Datei zurückgeben, indem ich die Funktion aufruft, in der er sich befindet. – Teddy

+0

Andrei wies darauf hin, wie man den 'name' außerhalb des Callbacks zur Verfügung stellt, indem man ihn der Variablen' name' der Komponente zuweist. Es ist nicht möglich, 'name' in Ihrem Fall synchron zurückzugeben. – Matt

+0

@Matt: Ich kann es nicht in 'Oninit' so verwenden. Was ist, wenn ich explizit zurückgeben muss, sieht mein Aufrufcode folgendermaßen aus: this.actions $ .ofType (SearchActions.SEARCH_MULTIPLE_NEW_QUERY) .map (toPayload) .fnWithMultipleAsyncReturns() ' – ishandutta2007

7

Ich weiß, dass diese Frage ganz vor einer Weile war und Sie sicherlich mittlerweile eine richtige Lösung, aber für alle, für diese Suche Ich würde vorschlagen, es mit einem Versprechen zu lösen, um das asynchrone Muster zu behalten. Eine ausführlichere Version würde ein neues Versprechen erschaffen:

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

Eine schlankere Lösung:

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

am empfangenden Ende haben Sie dann „wait“ für das Versprechen mit so etwas wie dieses Problem zu beheben

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

die Empfangsseite bleibt die gleiche wie oben natürlich: statt RxJS‘.toPromise() unter Verwendung wäre. Ich hoffe, das hilft!

2

Beobachtbare Werte können von beliebigen Standorten abgerufen werden. Die Quellsequenz ist zuerst geschoben auf einen speziellen Beobachter, der an anderer Stelle emittieren kann. Dies wird mit der Subject-Klasse von Reactive Extensions (RxJS) erreicht.

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

Wert speichern auf den Beobachter.

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

Themen sind beide Observablen und Beobachter:

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

Um den Wert von anderswo, abonnieren Sie den Beobachter wie so abzurufen. Es gibt andere Subject types wie BehaviourSubject und ReplaySubject für andere Verwendungsszenarien.

Vergessen Sie nicht, RxJS zu importieren.

var Rx = require('rxjs'); 
5

Wenn Sie möchten, auf die gleiche beobachtbare vorab abonnieren, der zurückgegeben wird, verwenden Sie einfach

.do():

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

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

Große Antwort .... Es löste mein Problem in solchen eine einfache Möglichkeit ..... +1 – Romesh

+0

Sie können auch andere Operatoren wie '.map (data => data)' verwenden, die das Gleiche tun und dann abonnieren, wo immer Sie das Ergebnis erwarten –

Verwandte Themen