2016-11-03 1 views
1

Könnte sein, dass ich ein Noob bin und nicht ganz verstehe, wie dieses Zeug noch funktionieren sollte, aber ich habe ein Epic in Redux-Observable, in dem ich als verwenden möchte eine Möglichkeit, ein Versprechen zu erstellen, das eine Aktion abliefert und auf eine andere Aktion wartet, bevor es aufgelöst wird. Ich habe es funktioniert, indem Sie die Aktion auf '__IGNORE__' Mapping, aber ich will das wirklich nicht tun. Gibt es eine Möglichkeit, ein Epic nur mit einer Aktion zu behandeln, aber nichts anderes weiterzugeben?Redux-Observable Epic, das keine neuen Aktionen sendet

Hier ist mein Code:

export const waitFor = (type, action) => new Promise((resolve, reject) => { 
    const waitForResult = action$ => action$.ofType(type).do(() => resolve()).mapTo({type: "___IGNORE___"}); 
    registerEpic(waitForResult); 

    action(); 
}); 

Antwort

7

Sie alle next'd Werte von einer beobachtbaren Kette unter Verwendung des .ignoreElements() RxJS Betreiber

action$.ofType(type) 
    .do(() => resolve()) 
    .ignoreElements(); 

Ein anderer Weg, dies zu tun (nicht mehr richtig wegwerfen kann oder falsch) ist eine anonyme Observable zu erstellen, die nur abonniert.

Dadurch wird das von uns erstellte Abonnement implizit zurückgegeben, sodass es auch an den Lebenszyklus unseres rootEpic angehängt ist. Da wir nie observer.next() aufrufen, gibt dieses Epos niemals irgendwelche Werte aus; genau wie ignoreElements().


Obwohl Sie nicht gefragt hat, können Sie schließlich feststellen, dass Ihr Epos für immer laufen, für die eingehende Aktion hören die type Variable entspricht. Dies ist möglicherweise nicht was Sie wollen, wenn Sie einmal dann abschließen möchten.

Sie können dies mit .take(1) Operator erreichen.

const waitForResult = action$ => 
    action$.ofType(type) 
    .take(1) 
    .do(() => resolve()) 
    .ignoreElements(); 

Oder

const waitForResult = action$ => new Observable(observer => 
    action$.ofType(type) 
    .take(1) 
    .subscribe({ 
     next:() => resolve(), 
     error: err => observer.error(err), 
     complete:() => observer.complete() 
    }) 
); 

Dies wird gemäß der Lebensdauer der Anwendung nur einmal übereinstimmen - einmal erhielt er wird es nie wieder tun.