在 NgRX Effect 中处理时,效果将不再起作用
When handling in NgRX Effect, the effect won't work anymore
我这辈子都想不通为什么一旦抛出并拦截了错误,效果就失效了
@Effect()
register$ = createEffect(() => {
return this.actions$.pipe(
ofType(RegisterAction),
map(action => action.registrationInfo),
mergeMap(registrationInfo => {
return this.authService.createUser(registrationInfo.email, registrationInfo.password,
registrationInfo.lastname, registrationInfo.firstname);
}),
map(credentialInfo => ProfileInitAction({credentialInfo})),
catchError(error => [ProfileInitErrorAction(error)]),
);
});
在 catchError 中添加 caught$ 似乎可以解决这个问题。
register$ = createEffect(() => {
return this.actions$.pipe(
ofType(RegisterAction),
map(action => action.registrationInfo),
mergeMap(registrationInfo => {
return this.authService.createUser(registrationInfo.email, registrationInfo.password,
registrationInfo.lastname, registrationInfo.firstname);
}),
map(credentialInfo => ProfileInitAction({credentialInfo})),
catchError((err, caught$) => {
notify(this.translate.instant('pages.auth.register.notify.error' + ': ' + err['message']), 'error');
return caught$;
}),
);
});
你知道为什么吗?因为这是 RXJS 中的正常工作流程。因此,可观察对象会在不同时间发出值。当发生错误时,可观察链(或管道或订阅,或您想要的)就会中断。你有一个服务电话。这个服务调用可能会失败,对吧?但是您在 child 可观察链中执行此服务调用。所以你可以处理这个 child 的可观察链中的错误,这不会破坏你的主要可观察链。一句话,做mergeMap中的catchError
例如:
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { EMPTY } from 'rxjs';
import { map, mergeMap, catchError } from 'rxjs/operators';
import { MoviesService } from './movies.service';
@Injectable()
export class MovieEffects {
loadMovies$ = createEffect(() => this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
mergeMap(() => this.moviesService.getAll() //< --- starting point of the child observable chain
.pipe(
map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
catchError(() => EMPTY) // <--- this is runs in the child observable chain
))
) // <--- end of the child observable chain
); // <--- end of the main observable chain
constructor(
private actions$: Actions,
private moviesService: MoviesService
) {}
}
我这辈子都想不通为什么一旦抛出并拦截了错误,效果就失效了
@Effect()
register$ = createEffect(() => {
return this.actions$.pipe(
ofType(RegisterAction),
map(action => action.registrationInfo),
mergeMap(registrationInfo => {
return this.authService.createUser(registrationInfo.email, registrationInfo.password,
registrationInfo.lastname, registrationInfo.firstname);
}),
map(credentialInfo => ProfileInitAction({credentialInfo})),
catchError(error => [ProfileInitErrorAction(error)]),
);
});
在 catchError 中添加 caught$ 似乎可以解决这个问题。
register$ = createEffect(() => {
return this.actions$.pipe(
ofType(RegisterAction),
map(action => action.registrationInfo),
mergeMap(registrationInfo => {
return this.authService.createUser(registrationInfo.email, registrationInfo.password,
registrationInfo.lastname, registrationInfo.firstname);
}),
map(credentialInfo => ProfileInitAction({credentialInfo})),
catchError((err, caught$) => {
notify(this.translate.instant('pages.auth.register.notify.error' + ': ' + err['message']), 'error');
return caught$;
}),
);
});
你知道为什么吗?因为这是 RXJS 中的正常工作流程。因此,可观察对象会在不同时间发出值。当发生错误时,可观察链(或管道或订阅,或您想要的)就会中断。你有一个服务电话。这个服务调用可能会失败,对吧?但是您在 child 可观察链中执行此服务调用。所以你可以处理这个 child 的可观察链中的错误,这不会破坏你的主要可观察链。一句话,做mergeMap中的catchError
例如:
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { EMPTY } from 'rxjs';
import { map, mergeMap, catchError } from 'rxjs/operators';
import { MoviesService } from './movies.service';
@Injectable()
export class MovieEffects {
loadMovies$ = createEffect(() => this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
mergeMap(() => this.moviesService.getAll() //< --- starting point of the child observable chain
.pipe(
map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
catchError(() => EMPTY) // <--- this is runs in the child observable chain
))
) // <--- end of the child observable chain
); // <--- end of the main observable chain
constructor(
private actions$: Actions,
private moviesService: MoviesService
) {}
}