angular - ngrx 效应进入无限循环的问题
问题描述
我知道这已经被问过很多次了,但我仍然无法理解我的代码出了什么问题。似乎我的效果已经服用了类固醇,并且根本没有停止无休止地运行。我在 ngrx/store 和 ngrx/effects 版本 10.1.1
下面是代码:
主页.effects.ts
public defaultState: DeployedInstanceModel;
@Effect()
loadDeployedInstanceData$ = this.actions$
.pipe(
ofType(DeployedInstancesTypes.GET_TABLE_DATA),
mergeMap(() => {
// reset default state before api call is made
this.defaultState = {
data: {}
};
return this.analyticsService.getDeployedInstanceData().pipe(
map(result => {
this.defaultState.data = result;
console.log('[deployed-instance] the result of api call is -> ', result);
return new DeployedInstanceGetData.GetDeployedInstanceAction(this.defaultState);
}),
catchError(err => {
let errObj = {err: '', url: ''}
errObj.err = err.statusText;
errObj.url = err.url;
console.log('API failure detected on the url -> ', errObj.url);
this.showErrorPopup();
return errObj.err;
})
);
})
)
constructor(
private actions$: Actions,
private analyticsService: AnalyticsService
) { }
这就是我尝试从家庭组件调度我的操作的方式
home.component.ts
ngOnInit(){
this.state = { data: {}};
// first dispatch empty state on page load
this.store.dispatch(new DeployedInstanceGetData.GetDeployedInstanceAction(this.state));
// get the data from the store once api has been called from effects
this.homeDeployedInstanceStore$ = this.store.select('deployedInstanceModel').subscribe(state => {
this.totalData = state.data;
if(Object.keys(this.totalData).length > 0){
console.log(this.totalData);
this.loader.stop();
}else{
this.loader.start();
}
console.log('[Deployed Instance] state from component -> ', this.totalData);
});
}
我尝试了什么:
我尝试了下面提到的所有解决方案:
@Effect({dispatch:false})
- 这里的数据被提取一次,但是this.store.select
当我有返回的数据在主页上显示的空数据时我没有被再次调用
take(1)
- 尝试使用此解决方案,但当用户导航出页面并再次返回同一页面时,我无法第二次调用 api。
尝试删除@Effect
但又遇到了同样的问题。
如果有人能指出我正确的方向,那将非常有帮助。
解决方案
我的建议是为每个异步请求的解析创建 3 个操作。示例:FetchData、FetchDataSuccess、FetchDataFailure。但!如果要处理 catchError 中的操作,则需要发出新的 observable。
我的项目中的示例:
export const FetchDraftAction = createAction(
'[GOALIE_TRACKER.TRACKER_DETAIL] FETCH_DRAFT',
props<{ uuid: string }>(),
);
export const FetchDraftSuccessAction = createAction(
'[GOALIE_TRACKER.TRACKER_DETAIL] FETCH_DRAFT_SUCCESS',
props<{ draft: DraftRecord }>(),
);
export const FetchDraftFailureAction = createAction(
'[GOALIE_TRACKER.TRACKER_DETAIL] FETCH_DRAFT_FAILURE',
);
并且这样做有效:
public fetchDraft$ = createEffect(() =>
this.actions$.pipe(
ofType(FetchDraftAction),
switchMap(({ uuid }) =>
this.matchStatService.getDraftByKey(uuid).pipe(
map(draft => FetchDraftSuccessAction({ draft })),
catchError(() => of(FetchDraftFailureAction())),
),
),
),
);
public fetchDraftSuccess$ = createEffect(() =>
this.actions$.pipe(
ofType(FetchDraftSuccessAction),
switchMap(() => [StopLoadingMessageAction()]),
),
);
public fetchDraftFailure$ = createEffect(() =>
this.actions$.pipe(
ofType(FetchDraftFailureAction),
switchMap(() => [StopLoadingMessageAction()]),
),
);
如您所见,catchError(() => of(FetchDraftFailureAction())),
在fetchDraft$
. 它从of(...)
操作员开始。那是因为您的效果会因错误而中断流,您需要使用新操作再次“启动”它。
这是我的建议。享受!
PS:我正在使用动作和效果创建器,但方法是相同的。
推荐阅读
- bash - 在 if 语句条件中为什么我不能执行函数并测试结果
- c++ - Windows Media Foundation MFCreateSourceReaderFromURL 函数中的内存泄漏。有什么替代功能吗?
- python - 使用 3 个指针反转链表
- python - 获取我们在数据框列中的所有字典键
- wordpress - 页面构建器中的 Wordpress RSS 提要
- wordpress - 联系表格 7 中的按钮单击和自动选择单选按钮
- sql - Python中的子查询
- linux - 如何修复“错误:未找到 .desktop 文件”以手动创建 AppImage
- python - Tensorflow Keras 模型 Load_Model 无法使用 Python 隐藏模型对象
- java - 从远程存储库安装 Maven 工件,如 npm install