2016-11-15 5 views
2

Ich bin immer noch ein Noob, wenn es um RxJS geht, aber hier ist ein JSBin von dem, was ich versuche zu tun.switchMap scheint nicht abgeschlossen zu sein, wenn die innere Observable abgeschlossen ist

https://jsbin.com/wusalibiyu/1/edit?js,console

Ich habe eine beobachtbare ‚a‘ (in meinem Fall ist es die aktuelle aktive Verbindung), die ein neues Objekt aussendet, sobald die Verbindung wieder verbindet. Es ist selbst beobachtbar, weil es einen neuen Wert wieder ausgeben kann.

Ich möchte jetzt eine Observable, die immer dann ausgeführt wird, wenn eine Aktion für die aktuelle Verbindung ausgeführt wird. Diese Aktion benachrichtigt sie, wenn das Observable für sie abgeschlossen ist. Dies ist b.

Das Problem ist, dass, wenn das innere Observable abgeschlossen ist, das äußere nicht abgeschlossen ist. Wie man das äußere Observable vervollständigt .... Gibt es einen anderen Operator, den ich in RxJS5 verwenden sollte?

Antwort

7

Wenn ich Ihre Anforderung richtig verstehen, können Sie „Lift“ der innere Strom ein materialize/dematerialize Paar mit heraus (man beachte ich auch als Teil meines nicht enden wollenden Krieg Refactoring Menschen zu verwenden Observable#create zu stoppen).

JsBin (Auszug unten)

function b(a) { 
    // Emit and complete after 100 millis 
    return Rx.Observable.timer(100) 

    // Ignore any values emitted 
    .ignoreElements() 

    // Emit the value on start 
    .startWith(a) 
    .do(() => console.log('creating observable')) 
    .finally(() => console.log('b done')); 
} 

var a$ = Rx.Observable.from(['a', 'b']) 
    .finally(() => console.log('a done')); 

var result$ = a$.switchMap(function(a) { 
    console.log('switching map for a to b', a); 

    // This "materializes" the stream, essentially it maps complete -> next 
    return b(a).materialize(); 
}) 
// This does the opposite, and converts complete events back, 
// but since we are now in the outer stream 
// this results in the outer stream completing as well. 
.dematerialize() 
.share(); 


result$.subscribe(function(value) { 
    console.log('value', value); 
}, function(e) { 
    console.error('e', e); 
}, function() { 
    console.log('completed!'); 
}) 

result$.toPromise().then(function(data) { 
    console.log('this should trigger!?', data); 
}, function(e) { 
    console.error('boom', e.toString()); 
}); 
+0

Ich kopierte Code von meinem Projekt so eng wie möglich, um die Situation so gut wie möglich zu replizieren. In meinem Code wickle ich eine Drittanbieterbibliothek in eine Observable ein. Ich glaube in diesem Fall ist es richtig. Aber materialisieren/dematerialisieren ist eindeutig was ich vermisst habe. Vielen Dank für das Angebot der Lösung! – SpoBo

Verwandte Themen