在史诗中的可观察流的开始和结束时发出动作的最佳实践方法?
Best practice approach to emit an action at the start and end of a stream of observables in an epic?
我正在使用 react-observable 来协调我的应用程序中的 AJAX 调用。我已连接 react-redux-loading-bar 以在 AJAX 调用开始时显示加载栏,并在调用完成时隐藏它。能用但感觉不是很'clean'。
有没有更好的方法来利用 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);
更新:
在研究了 Martin 关于使用 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);
好吧,我从未使用过 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)
是什么,所以我假设它们不会 return Observables(尽管它们有 fetch*
前缀)。
此外,您真的需要 showLoading()
和 hideLoading()
return 值重新发送并成为链的一部分吗?
我正在使用 react-observable 来协调我的应用程序中的 AJAX 调用。我已连接 react-redux-loading-bar 以在 AJAX 调用开始时显示加载栏,并在调用完成时隐藏它。能用但感觉不是很'clean'。
有没有更好的方法来利用 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);
更新:
在研究了 Martin 关于使用 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);
好吧,我从未使用过 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)
是什么,所以我假设它们不会 return Observables(尽管它们有 fetch*
前缀)。
此外,您真的需要 showLoading()
和 hideLoading()
return 值重新发送并成为链的一部分吗?