2016-08-05 44 views
6

Ich bin ziemlich neu zu RxJs und ich würde gerne verstehen, was der beste Weg ist, mit Rx in Kombination mit Promises zu arbeiten.RxJs Erstellen Observable aus resultierenden Versprechen

Was ich erstellen möchte, ist ein Dienst in Angular, der viel wie ein Event-Dispatcher-Muster fungiert und ein Ereignis ausgibt, sobald ein Versprechen abgeschlossen ist. Was ich auch benötige ist, dass, wenn es keine (Event-) Abonnenten gibt, das Observable nie aufgerufen wird. Das letzte, was ich möchte, ist, dass nachfolgende Abonnenten der Observablen das gleiche Ergebnis erhalten, ohne eine weitere Anfrage an den Server auszulösen. Ich habe es geschafft, meine eigene Lösung zu implementieren hier:

// ... CountryService code 

var COUNTRIES_LOADED = Rx.Observable 
    .create(function (observer) { 
     $http 
      .get('/countries') 
      .then(function (res) { 
       observer.onNext(res); 
      }, function (err) { 
       observer.onError(err); 
      }) 
      .finally(function() { 
       observer.onCompleted(); 
      }); 
    }) 
    .shareReplay(); 

nun jederzeit abonniere ich einen neuen „Zuhörer“, um die beobachtbaren unterliegt, gezogen werden. Alle neuen Abonnenten erhalten den Wert zwischengespeichert, ohne den Server erneut zu berühren.

Also in meinem „Verbraucher“ (Angular-Richtlinie) Ich möchte so etwas wie dies tun:

// ... countryInput directive code: 

COUNTRIES_LOADED.subscribe(function (response) { 
    // Fill in countries into scope or ctrl 
    scope.countries = response.countries; 
}); 

Irgendwelche Zukunft Abonnenten des COUNTRIES_LOADED Beobachter darf kein $ HTTP-Anforderung auslösen. Wenn die Direktive niemals auf der Seite enthalten ist, wird $ http niemals aufgerufen.

Die obige Lösung funktioniert, mir sind jedoch die möglichen Nachteile und Speicherauswirkungen dieses Ansatzes nicht bekannt. Ist das eine gültige Lösung? Gibt es einen besseren/geeigneteren Weg, dies mit RxJs zu erreichen?

Vielen Dank!

+1

Prüfung Link rxjs mit AngularJS http://cvuorinen.net/2016/05/using-rxjs-observables-with-angularjs-1/ –

+0

Ihre Lösung mit sieht gut aus, ich glaube nicht, dass Sie sich etwas Besseres einfallen lassen können. – estus

Antwort

1

Haben Sie versucht, die fromPromise() API von rxjs5 zu verwenden?

Überprüfen Sie die Dokumentation here!

+0

Ja, mir ist das fromPromise bekannt, aber das passiert nur, wenn bereits ein Versprechen vorliegt. Was ich benötige, ist, dass ein $ http Aufruf nie ausgeführt wird, wenn es keine Abonnenten für das Observable gibt – Max101

1

So können Sie Observables verwenden Nehmen wir an, Sie haben eine Methode namens getuser(username).

//Returns an observable 
getUser(username){ 
    return $http.get(url) 
     .map(res => res.json()); 
} 

Und Sie können es verwenden, wie unten

getUser.subscribe(res => console.log(response)); 

aber wenn Sie verspricht

//Returns an Promise 
//Donot forget to import toPromise operator 
getUser(username){ 
    return $http.get(url) 
     .map(res => res.json()) 
     .toPromise(); 
} 

verwenden möchten, und Sie es wie unten

getUser.then(res => console.log(response)); 
+0

Ok Entschuldigung vielleicht war die Frage nicht sehr klar. Ich weiß, wie man Observable verwendet und konsumiert. Was ich wissen möchte, ist, wie man einen HTTP-Call in eine Observable "einwickelt", die nur dann aufgerufen wird, wenn UND/NUR wenn es irgendwelche Abonnenten gibt. – Max101

+0

Das Hauptproblem bei dieser Antwort ist, dass '$ http.get' * * kein Observable zurückgibt. Es gibt ein Versprechen zurück. Das ist der große Unterschied zwischen Angulars "Http" und AngularJs "$ http". – daemonaka

4

ich verwenden kann, fand die Antwort hier (Nur etwas anders ntly genannt) rxjs using promise only once on subscribe

Also für mein Beispiel die Antwort ist so einfach wie:

var loadCountries = function() { return $http.get('/countries'); }; 

var observable = Rx.Observable.defer(loadCountries).shareReplay(); 
2

Verwenden Rx.Observable.fromPromise(promise)

fromPromise:

Wandelt ein Versprechen/A + spec konforme Promise und/oder ES2015 konform Promise oder eine Factory-Funktion, die das Versprechen an eine beobachtbare Sequenz zurückgibt.

Beispiel:

var source = Rx.Observable.fromPromise(promise); 

var subscription = source.subscribe(
    function (x) { 
    console.log('Next: %s', x); 
    }, 
    function (err) { 
    console.log('Error: %s', err); 
    }, 
    function() { 
    console.log('Completed'); 
    });