NgRx效应,发生故障,不接受新的行动。

问题描述 投票:0回答:1
@Injectable()
export class UserEffects {
  constructor(
    private store$: Store<fromRoot.State>,
    private actions$: Actions,
    private router: Router,
    private chatService: ChatService,
    private authService: AuthService,
    private db: AngularFireAuth,
    private http: HttpClient
  ) { }

  @Effect()
  login$: Observable<Action> = this.actions$.pipe(
    ofType(UserActions.LOGIN),
    switchMap((action: UserActions.LoginAction) =>
      from(this.db.auth.signInWithEmailAndPassword(action.payload.email, action.payload.password)),
    ),
    // switchMapTo(from(this.db.auth.currentUser.getIdToken())),
    switchMapTo(from(this.db.authState.pipe(
      take(1),
      switchMap((user)=>{
        if (user)
          return from(user.getIdToken());
        else
          return of(null);
      })
    ))),
    switchMap(token => this.http.post(environment.apiUrl + '/api/login', { token: token })),
    tap((response: any) => {
      if (response.valid === 'true') {

        localStorage.setItem('token', response.token);

        this.router.navigate(['dash']);

      }
    }),
    map(response => new UserActions.LoginSuccessAction({ response })),
    catchError(error => {
      return of({
        type: UserActions.LOGIN_FAILURE,
        payload: error
      });
    })
  );

  @Effect({ dispatch: false })
  loginSuccess$: Observable<Action> = this.actions$.pipe(
    ofType(UserActions.LOGIN_SUCCESS),
    tap((action: UserActions.LoginSuccessAction) => {
      console.log("LOGIN_SUCCESS");
      console.log(action);
    }));

    @Effect({ dispatch: false })
    loginFailure$: Observable<Action> = this.actions$.pipe(
      ofType(UserActions.LOGIN_FAILURE),
      tap((action: UserActions.LoginFailureAction)=>{
        console.log("LOGIN_FAILURE");
        console.log(action.payload.code);
      }));
}

用例:你在一个登录页面。你输入用户名和密码来调用LoginAction。如果一切顺利,就应该调用LoginSuccessAction,否则就应该调用LoginFailureAction。否则,应该调用LoginFailureAction。

除了一种情况外,一切都能正常工作。 一旦LoginFailureAction被调用一次, LoginSuccessAction和LoginFailureAction都不会再被调用. 我不知道为什么会发生这种情况。我想这可能和这一行有关系。

catchError(error => {
  return of({
    type: UserActions.LOGIN_FAILURE,
    payload: error
  });
})

但在这里我就不明白了 我不是反应式编程的专家,但除了这一个案例,所有的工作都是应该的。有人知道为什么会出现这种情况吗?

javascript angular rxjs ngrx ngrx-effects
1个回答
1
投票

效果包括成功完成和错误。如果出现错误,ngrx会重新订阅,如果成功完成,则不会。

例如 catchError 可能导致这种情况,因为它不监听它的父流。如果你想在发生错误时启用流,你需要使用 repeat 后面的运算符 catchError.

    catchError(error => {
      return of({
        type: UserActions.LOGIN_FAILURE,
        payload: error
      });
    }),
    repeat(), // <- now effect is stable.

0
投票

你必须添加 catchError 在每一个内在的可观察到的事物上,例如。

switchMap(token => this.http.post(environment.apiUrl + '/api/login', { token: token }).pipe(catchError(...)),

参见 处理错误 在NgRx文档中的 "NgRx "一节了解更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.