您好,并提前致谢:)
我想推出具体的动作$ 史诗来自redux-observable 取决于路线,并在路线更改时取消它们。 此外,我想在取消史诗时处理一些清理工作。我已经做了。但是:
我使用 state.dispatch(actions.signInError({}))
进行清理(已弃用),并且不知道如何以其他方式执行 。我的代码在下面,问题就在最后。
/**
* Launch route specific actions if such exist and cancel previous one
*
* @param {Function} action$ - redux-observable action$
* @param {Object} state - redux state
*/
const addEpicsForRoute = (action$, state) => action$
.ofType(LOCATION_CHANGE) // action from route
.switchMap(
( action ) => {
// get epics for route
const epicsForRoute = routeEpics[ action.payload.pathname ];
if ( epicsForRoute ) {
return merge(
...epicsForRoute.map(observableCreator => observableCreator(action$, state))
);
} else {
return empty(); // no specific epics
}
}
);
/**
* Handle xhr request-response/error logic of sign in user
*
* @param {Function} action$
* @param {Object} state
*/
export const signIn = ( action$, state ) => {
return action$
.ofType(types.SIGN_IN_REQUEST)
.mergeMap(( { params, } ) => (
Observable.create(observer => {
services
.signInRequest( // it is ajax observable
mappers.mapSignInRequest(params)
)
.map(response => actions.signInJWTSuccess( // dispatch success
mappers.mapUser(response)
))
.catch(error => of(actions.signInError( // dispatch error
mappers.mapSignInError(error)
)))
.subscribe(( value ) => { // pass action to redux-store
observer.next(value);
});
return () => {
// cleanup logic. HERE IS A PROBLEM
// calling store.dispatch() directly in your Epics is deprecated and will be removed.
// what should I use instead?
state.dispatch(actions.signInError({}));
};
})
));
};
此外,我是rxjs的新手,如果你有一个建议,我可以改进或使外观代码更漂亮,我感兴趣!
答案 0 :(得分:0)
我建议查看代码流程,以充分利用Observables运算符的强大功能。
一个想法可能是沿着这些方向前进
signIn
通过这种方式,您创建了一个函数signIn
,它返回一个Observable,它发出signIn ajax调用的结果。
然后,我会创建另一条逻辑来订阅const subscription = signIn(action, state)
.subscribe(
value => {// do what needs to be done with the result of the signIn call},
err => {// insert here the logic to handle error conditions},
() => {// do here what needs to be done when the Observable completes
// consider that ajax calls complete after the first emit, therefore
// you can put this part of logic also within the first callback, the one passed as the first parameter to subscribe() method
}
)
返回的此类Observable,并决定做什么,例如
create
请注意,您还将订阅存储在变量中,您可以使用该变量在路线更改时取消订阅。
您放入cbrain_school
方法返回的函数的清理逻辑可能会移动到您实际取消订阅订阅的位置,因为您移动到另一条路径。
答案 1 :(得分:0)
我认为一个好问题是这是否是正确的期望。当您使用switchMap
时,您取消订阅内部Observable,这意味着您不再希望接收其排放。那么当您取消订阅时它会发出另一个动作是否有意义?
无论如何,你可以merge
另一个只发出清理行为的链的Observable。
const action$ = new Subject();
const cleanup$ = new Subject();
action$
.pipe(
switchMap(() => new Observable(observer => {
// whatever goes here
observer.next('Observable created');
return () => {
cleanup$.next(/* create proper action here */ 'cleanup');
};
})),
merge(cleanup$),
)
.subscribe(console.log);
action$.next(1);
action$.next(2);
我没有使用真正的redux-observable
行动,但我希望你明白这一点。
现场演示(开放式控制台):https://stackblitz.com/edit/rxjs5-9iogn1?file=index.ts