角NgRx的效果创建了一个无限循环

时间:2019-07-14 15:18:12

标签: angular rxjs ngrx

首先值得一提的是我还不太清楚rxjs的运算符。我研究了它们,但在实际操作中,如果我使用switchMap,mergeMap或map,结果仍然看起来相同。

下面的代码创建了一个无限循环,我试图策略性地放置调试器以了解流程,但是它必须与HTTP响应时间严格相关,因此似乎以非常随机的方式在效果之间跳转。

@Effect()
addNewDocument = this.actions$.pipe(
    ofType(UserActions.ADD_DOCUMENT),
    map((action: UserActions.AddNewDocument) => {
        return action.document;
    }),
    switchMap((document: FormData) => {
        return this.store.select('user').pipe(
            map((user) => {
                return {
                    document,
                    uuid: user.uuid
                };
            })
        );
    }),
    switchMap((payload: { document: FormData, uuid: string }) => {
        return this.httpClient.post(
            `${environment.apiUrl}user/${payload.uuid}/documents`,
            payload.document
        ).pipe(
            mergeMap((response: any) => {
                return [
                    {
                        type: UserActions.ADDED_DOCUMENT,
                        response
                    }
                ];
            }),
            catchError((error) => of(new AppActions.GenericError(error)))
        );
    })
);

@Effect({dispatch: false})
addedNewDocument = this.actions$.pipe(
    ofType(UserActions.ADDED_DOCUMENT),
    tap(() => {
        this.router.navigate(['/user/documents']);
    })
);

我的意图是:

  1. 拦截UserActions.ADD_DOCUMENT操作
  2. 跟踪http请求的uuid
  3. 发出请求并通过事件UserActions.ADDED_DOCUMENT处理响应,以便通过其reducer更新状态

如果您能帮助我了解问题所在,我将不胜感激。如果您认为我误用了某些运算符,或者您知道使用它们的更好方法,请告诉我。

谢谢。

1 个答案:

答案 0 :(得分:1)

看来您的user状态在您的应用程序中正在改变,这导致了效果的循环。在使take(1)状态生效的同时尝试使用user

switchMap((document: FormData) => {
        return this.store.select('user').pipe(
            take(1),
            map((user) => {
                return {
                    document,
                    uuid: user.uuid
                };
            })
        );
    })

take(1)将完成可观察的动作,并将拆除该动作,直到调度下一个UserActions.ADD_DOCUMENT动作为止。 希望对您有所帮助。