2016-11-04 3 views
2

Ich benutze React-Observable, um die AJAX-Aufrufe in meiner Anwendung zu orchestrieren. Ich habe in react-redux-loading-bar verdrahtet, um einen Ladebalken anzuzeigen, wenn die AJAX-Aufrufe beginnen und ihn ausblenden, wenn sie fertig sind. Es funktioniert, aber es fühlt sich nicht sehr "sauber" an.Best-Practice-Ansatz, um am Anfang und am Ende eines Stroms von Observablen in einem Epos eine Aktion auszulösen?

Gibt es eine bessere Möglichkeit, RXJS oder Redux-Observable zu nutzen, um diese sauberer zu machen?

import Rx from "rxjs"; 
import {combineEpics} from "redux-observable"; 
import client from "../../integration/rest/client"; 

import {showLoading, hideLoading} from 'react-redux-loading-bar' 

import * as types from "./actionTypes"; 
import * as actions from "./actions"; 

const fetchEpic = action$ => 
    action$.ofType(types.FETCH) 
     .mergeMap(action => 
      Rx.Observable.of(showLoading()).merge(
       client({method: 'GET', path: '/api'}) 
        .mergeMap(payload => Rx.Observable.of(actions.fetchSuccess(payload), hideLoading())) 
        .catch(error => Rx.Observable.of(actions.fetchFailure(error), hideLoading())) 
      ) 
     ); 

export default combineEpics(fetchEpic); 

UPDATE:

Nach einem Blick in Martins Vorschlag von concat ich mit einer vereinfachten Version angebracht habe, die ich bin glücklich mit.

import Rx from "rxjs"; 
import {combineEpics} from "redux-observable"; 
import client from "../../integration/rest/client"; 

import {showLoading, hideLoading} from 'react-redux-loading-bar' 

import * as types from "./actionTypes"; 
import * as actions from "./actions"; 

const fetchEpic = action$ => 
    action$.ofType(types.FETCH) 
     .mergeMap(action => 
      Rx.Observable.merge(
       Rx.Observable.of(showLoading()), 
       client({method: 'GET', path: '/api'}) 
        .map(payload => actions.fetchSuccess(payload)) 
        .catch(error => Rx.Observable.of(actions.fetchFailure(error))) 
        .concat(Rx.Observable.of(hideLoading())) 
      ) 
     ); 

export default combineEpics(fetchEpic); 

Antwort

3

Nun, ich habe noch nie redux-observable verwendet, aber ich glaube, Sie haben so viele merge Anrufe während Sie sie nicht benötigen, weil Sie nicht mit einem Wert, den sie weitergeben an ihre Rückruf arbeiten. Ich würde persönlich usign concat bevorzugen, weil dann ist es offensichtlich, dass du Werte von Obseravbles um emittieren wollen:

const fetchEpic = action$ => 
    action$.ofType(types.FETCH) 
     .startWith(showLoading()) 
     .concat(client({method: 'GET', path: '/api'}) 
      .concatMap(payload => Rx.Observable.of(actions.fetchSuccess(payload))) 
      .catch(error => Rx.Observable.of(actions.fetchFailure(error))) 
     ) 
     .concat(Rx.Observable.of(hideLoading()) 
    ); 

Ich weiß nicht, was actions.fetchSuccess(payload) oder actions.fetchFailure(error) so gehe ich davon aus sie nicht Observable zurückkehren (dispite ihre fetch* Präfix).

Benötigen Sie auch wirklich showLoading() und hideLoading() Rückgabewerte, die zurückgeliefert werden müssen und Teil der Kette?

+0

Ihr Beispiel funktioniert nicht so gut mit redux-observable, aber Ihr Vorschlag, concat zu betrachten, war genau das, was ich brauchte, um es ein wenig zu vereinfachen. Ich werde die aktualisierte Version veröffentlichen und diese als Antwort markieren; Angenommen, niemand schlägt Ihren Vorschlag bis zum Ende des Tages. –

Verwandte Themen