【问题标题】:Dispatching multiple actions with @ngrx/effects while making sure they are executed in order使用@ngrx/effects 调度多个动作,同时确保它们按顺序执行
【发布时间】:2017-12-06 10:26:02
【问题描述】:

我很好奇在返回多个操作作为对其他操作的响应时,是否有任何方法可以确保 @ngrx/effects 中的操作顺序。

ActionA => emit ActionB (=> emit async ActionB1, ActionB2) and then ActionC

我想实现ActionAActionBActionB1ActionB2ActionC的序列。

可以使用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


    【解决方案1】:

    有点晚了,但仍然是最新的。您可以使用效果来确定触发操作的顺序,即使没有 side-http-requests 或其他东西。通过这种方式,您可以轻松设置一系列操作。使用最新的 NgRX 效果语法,它看起来如下所示:

    首先设置一个在actionA之后触发actionB的效果。

    effect1$ = createEffect(() => this.actions$.pipe(
      ofType(actionA),
      mapTo(actionB())
    ));
    

    actionB 执行后,您可以定义它应该触发actionB1。您还可以传递有效载荷。

    effect2$ = createEffect(() => this.actions$.pipe(
      ofType(actionB),
      map(payload => actionB1(payload)
    ));
    

    当然应该有适当的效果名称等等。但希望你明白这一点。只需使用ofTypemap 指定顺序即可。


    在您的现实世界示例中,您还需要“响应”操作,例如 loginSuccessloginFailedlogoutSuccess 等。有了这些,只需使用上述方法来创建一口井定义的动作序列。

    【讨论】:

      猜你喜欢
      • 2020-01-25
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      • 2017-01-01
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 2019-09-07
      相关资源
      最近更新 更多