【发布时间】:2019-12-10 12:40:43
【问题描述】:
在将某些功能 Effects 切换到新的 createEffct() 模式后,它们调用的所有服务请求现在都会在我的控制台输出中触发两次。
下面是动作:
export const getSetting = createAction(
'[Practitioner Settings] Get Setting',
props<{ name: string }>(),
);
这是一个使用旧语法的效果示例:
@Effect()
getSetting$: Observable<Action> = this.actions.pipe(
ofType(PractitionerSettingsActionTypes.GetSetting),
map((action: PractitionerSettingsActions.GetSetting) => action.name),
switchMap((name: string) => {
return this.practitionerSetingsService
.getSetting(name)
.pipe(
map(response => new PractitionerSettingsActions.GetSettingSuccess(response)),
)
}),
);
以及新语法,基于以下示例:https://github.com/ngrx/platform/blob/master/projects/example-app/src/app/books/effects/collection.effects.ts:
@Effect()
getSetting = createEffect(() =>
this.actions.pipe(
ofType(PractitionerSettingsActions.getSetting),
mergeMap(({ name }) => {
return this.practitionerSetingsService
.getSetting(name)
.pipe(
map(response => PractitionerSettingsActions.getSettingSuccess({ setting: response })),
)
}),
)
);
我怀疑是 mergeMap 运算符导致了这种行为,因为它是两者之间的唯一区别,但我不确定它为什么会导致这种情况,或者如何以其他方式访问操作的有效负载。
除了将 Ngrx Actions、Reducers 和 Effects 更新为 v8 模式之外,我没有对我的应用程序进行任何其他更改,这会导致服务调用被执行两次。
如果不是 mergeMap,我应该使用什么运算符来访问操作负载?如果 mergeMap 是正确的,为什么我的效果会运行不止一次?
【问题讨论】:
-
作为测试,您可以在某处添加
this.actions.subscribe((action) => console.log(action))吗?这样,如果您的操作多次触发,您可以缩小范围。switchMap一次只允许一个内部订阅处于活动状态。一旦有新订阅,它就会取消任何活动的内部订阅。mergeMap没有这种相同的取消效果。每个内部订阅都会运行。 learnrxjs.io/operators/transformation/mergemap.htmllearnrxjs.io/operators/transformation/switchmap.html -
让我试一试
-
我在每个服务方法中都添加了一个日志语句。将
mergeMap更改为switchMap会产生相同的结果。对于 Effect 调用的每个方法,我仍然在控制台中看到我的日志语句两次。 -
为了验证,我切换到我的开发分支,用旧模式运行代码,每个服务方法我只看到一个日志语句。
标签: angular ngrx ngrx-effects