我是Observables和反应式编程rxjs的新手,我已将库redux-observable添加到我的react / redux应用程序中以开始使用它。
我为登录过程创建了一个史诗,基本上我想要的是,一旦触发了LOGIN_REQUEST动作,首先我启动SET_LOADING动作,在操作未完成时向用户显示旋转轮,然后我向服务器发出休息请求以获取用户。
这是我写的代码:
const loginEpic = (action$) => {
console.log('EPIC LOGIN EXECUTED');
return action$.filter(action => action.type === LOGIN_REQUEST)
.mergeMap(action => ajax.post(getUrl(constants.LOGIN),
action.payload))
.map(response => setUser(response.response))
.takeUntil(action$.ofType(LOGIN_REQUEST_CANCELLED));
.startWith(setLoading(true));
};
我一直使用运算符startWith启动SET_LOADING操作,一旦触发了LOGIN_REQUEST(这是我期望的行为)。 但是,我不知道为什么在首次加载应用程序时触发了SET_LOADING操作,甚至没有先前的LOGIN_REQUEST操作。
我知道问题与startWith运算符有关,因为如果删除,则不会触发SET_LOADING操作。那么,我做错了什么?为什么始终触发此SET_LOADING操作,而不仅仅是在LOGIN_REQUEST操作之后?
由于
答案 0 :(得分:3)
Epic只是一个可观察的,只要它产生一个动作就会被发送。如果你像这样使用startWith,那你就说任何开始订阅的人都会立即收到setLoadingAction。相反,只有在过滤器为真时才应该提高loadingAction。
这些方面的东西:
const loginEpic = (action$) => {
console.log('EPIC LOGIN EXECUTED');
return action$.filter(action => action.type === LOGIN_REQUEST)
.mergeMap(action => Observable.merge(
Observable.of(setLoading(true)),
Observable.fromPromise(ajax.post(getUrl(constants.LOGIN),
action.payload))
.map(response => setUser(response.response))
.takeUntil(action$.ofType(LOGIN_REQUEST_CANCELLED)));
};