如何使用RxJS实现此方案。
当我想获取用户(第一来源)时,我需要检查互联网连接(第二来源)。如果未连接互联网,则将第一个源排队,直到互联网重新打开。如果互联网重新打开,请发出第一个信号源。我可以制作下一个,但是直到第二个源为真时,我才开始思考如何排队第一个源。
请在这里检查我的代码:
const userEpic = action$ =>
action$.ofType(USER_REQUEST)
.withLatestFrom(action$.ofType(CONNECTION))
.filter(([first, second]) => second.value === true)
.do(a => console.log('can fetch a user'))
.mapTo({ type: SUCCESS });
http://jsbin.com/zomikukiqi/1/edit?js,console,output
最佳答案
尝试buffer()
存储USER_REQUEST,直到CONNECTION触发缓冲区刷新。
const USER_REQUEST = 'USER_REQUEST';
const CONNECTION = 'CONNECTION';
const SUCCESS = 'SUCCESS';
const requestUser = () => ({ type: USER_REQUEST });
const connection = (x) => ({ type: CONNECTION, value: x });
const bufferedUserRequests$ = (action$, store) =>
action$.ofType(USER_REQUEST)
.filter(x => !store.getState().connectionStatus)
.buffer(action$.ofType(CONNECTION))
const unbufferedUserRequests$ = (action$, store) =>
action$.ofType(USER_REQUEST)
.filter(x => store.getState().connectionStatus)
.map(request => [request])
const userEpic = (action$, store) =>
Rx.Observable.merge(
bufferedUserRequests$(action$, store),
unbufferedUserRequests$(action$, store)
)
.flatMap(bufferArray =>
bufferArray.map(request => Rx.Observable.of(request))
)
.do(a => console.log('can fetch a user'))
.mapTo({ type: SUCCESS })
const reducer = (state = { connectionStatus: false}, action) => {
switch (action.type) {
case CONNECTION:
return { ...state, connectionStatus: action.value }
default:
return state;
}
};
// components/App.js
const { connect } = ReactRedux;
let App = ({ requestUser, connection, connectionStatus }) => (
<div>
<button onClick={requestUser}>Start Request</button>
<p>Internet Connection: {connectionStatus.toString()}</p>
<button onClick={() => connection(false)}>Disconnect</button>
<button onClick={() => connection(true)}>Connect</button>
</div>
);
App = connect(
({ connectionStatus }) => ({ connectionStatus }),
{ requestUser, connection }
)(App);
// redux/configureStore.js
const { Provider } = ReactRedux;
const { createStore, applyMiddleware } = Redux;
const { createEpicMiddleware } = ReduxObservable;
const epicMiddleware = createEpicMiddleware(userEpic);
const store = createStore(reducer,
applyMiddleware(epicMiddleware)
);
// index.js
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
<script src="https://unpkg.com/[email protected]/dist/react.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-dom.min.js"></script>
<script src="https://unpkg.com/redux@^3.5.2/dist/redux.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-redux.min.js"></script>
<script src="https://unpkg.com/@reactivex/rxjs/dist/global/Rx.js"></script>
<script src="https://unpkg.com/redux-observable/dist/redux-observable.min.js"></script>
<div id="root"></div>