Наилучший подход к созданию действия в начале и в конце потока наблюдаемых в эпопее?

Я использую react-observable для организации вызовов AJAX в своем приложении. Я подключил панель react-redux-loading-bar, чтобы отображать панель загрузки, когда начинаются вызовы AJAX, и скрывать ее, когда они заканчиваются. Это работает, но не очень "чисто".

Есть ли лучший способ использовать RXJS или redux-observable, чтобы сделать это чище?

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

ОБНОВИТЬ:

Изучив предложение Мартина об использовании 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);

person Herbie Porter    schedule 04.11.2016    source источник


Ответы (1)


Ну, я никогда не использовал redux-observable, но я думаю, что у вас так много вызовов merge, хотя они вам не нужны, потому что вы не работаете со значением, которое они передают в свой обратный вызов. Лично я бы предпочел использовать 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), поэтому я предполагаю, что они не возвращают Observables (несмотря на их префикс fetch*).

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

person martin    schedule 04.11.2016
comment
Ваш пример не совсем работает с наблюдаемым с редуксом, но ваше предложение взглянуть на concat было именно тем, что мне нужно, чтобы немного упростить его. Я опубликую обновленную версию и отмечу это как ответ; при условии, что к концу дня никто больше не превзойдет ваше предложение. - person Herbie Porter; 04.11.2016