【发布时间】:2017-12-06 10:26:02
【问题描述】:
我很好奇在返回多个操作作为对其他操作的响应时,是否有任何方法可以确保 @ngrx/effects 中的操作顺序。
ActionA => emit ActionB (=> emit async ActionB1, ActionB2) and then ActionC
我想实现ActionA、ActionB、ActionB1、ActionB2、ActionC的序列。
可以使用concatMap,但这似乎不能确保在发出 C 之前已经处理了动作 B1 和 B2。
现实世界的例子:
@Effect()
oauthLoginAsSomeoneElse$: Observable<Action> = this.actions$
.ofType<AuthActions.OAuthLoginAsSomeoneElse>(AuthActions.OAUTH_LOGIN_AS_SOMEONE_ELSE)
.pipe(
concatMap(action => [
// First logout
new AuthActions.OAuthLogout(),
// Then login again
new AuthActions.OAuthLogin({redir: action.payload.redir})
])
);
@Effect({dispatch: false})
oauthLogin$: Observable<Action> = this.actions$
.ofType<AuthActions.OAuthLogin>(AuthActions.OAUTH_LOGIN)
.pipe(
map(action => oauthRedir.start(
this.authEndpoint + '/oauth/authorize',
this.authClientId,
this.authRedirectUri,
this.appBaseHref,
action.payload.redir,
))
);
@Effect()
oauthLogout$: Observable<Action> = this.actions$
.ofType<AuthActions.OAuthLogout>(AuthActions.OAUTH_LOGOUT)
.pipe(
switchMap(action =>
this.http.post(`${this.authEndpoint}/logout`, null, {withCredentials: true}).pipe(
map(responseData => new AuthActions.SessionTerminate()),
catchError((err: HttpErrorResponse) => {
return of(new RouterActions.Go({path: ['/']}));
}),
)
)
);
您会期望,在调度OAuthLoginAsSomeoneElse 时,与OAuthLogout 操作相关的所有内容都将在再次发出OAuthLogin 之前完成(包括@Effect() 发出的操作中的一些异步内容)。我的意思是,首先处理第一个根操作及其子项,然后处理下一个发出的根操作。
你知道这个场景是如何实现的吗?我目前的解决方法是提供下一个动作作为参数发送给OAuthLogout,但这并不能很好地扩展,并且很快就会变得非常复杂。
【问题讨论】:
标签: angular rxjs5 ngrx ngrx-effects