2016-11-04 1 views
2

Я использую реакцию, наблюдаемую для оркестровки вызовов AJAX в своем приложении. Я подключился к блоку «реакция-редукция-загрузка», чтобы показать загрузочную панель при запуске AJAX и скрыть ее при завершении. Он работает, но он не чувствует себя «чистым».Лучший практический подход для испускания действия в начале и конце потока наблюдаемых в эпопее?

Есть ли лучший способ использовать RXJS или редукцию, чтобы сделать это чище?

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:

Посмотрев на предложение Мартина с помощью CONCAT Я приложил упрощенную версию, которую я доволен.

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

ответ

3

Ну, я никогда не использовал redux-observable, но я думаю, что вы так много merge вызовов, которые вам не нужно, потому что вы не работаете со значением они переходят к их обратному вызову. Я лично предпочитаю usign concat, потому что тогда это очевидно, что вы хотите, чтобы испустить значения из Obseravbles в порядке:

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

Я не знаю, что actions.fetchSuccess(payload) или actions.fetchFailure(error), так что я предполагаю, что они не возвращают Наблюдаемые (dispite их fetch* префикс).

Кроме того, вам действительно нужны showLoading() и hideLoading() возвращаемые значения, которые нужно повторно использовать и часть цепочки?

+0

Ваш пример не совсем подходит для наблюдаемых сокращений, но ваше предложение взглянуть на concat было именно тем, что мне нужно было немного упростить. Я отправлю обновленную версию и пометьте это как ответ; предполагая, что никто другой не превзойдет ваше предложение к концу дня. –