如何使用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>

09-18 12:54