首先值得一提的是,我仍然不太清楚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']);
})
);
我的意图是:
- 拦截UserActions.ADD_DOCUMENT操作
- 跟踪 HTTP 请求的 UUID
- 通过事件UserActions.ADDED_DOCUMENT发出请求并处理响应,以便通过其化简器更新状态
如果您帮助我了解出了什么问题,我将不胜感激。如果您认为我错过了一些运算符,或者您知道使用它们的更好方法,请告诉我。
提前谢谢你。
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
操作被派出。希望对您有所帮助。