NgRx效果无限循环

时间:2019-08-27 16:32:43

标签: angular observable ngrx ngrx-effects

我知道这个问题在SO上已经问了一百万遍了。但是我需要帮助。我确实意识到我在这里必不可少的东西。但是我没看到。

以下代码触发无限循环。 REMOVE_PROJECT仅被调度一次。 REMOVE_PROJECT_SUCCESS被无限触发。 “已删除”被无限记录。我不知道为什么。

所有动作都有唯一的类型。已为REMOVE_PROJECT_SUCCESS启用dispatch: false

操作:

export const REMOVE_PROJECT = createAction(
    '[Project] Remove Project',
    props<{ id: string }>()
);

export const REMOVE_PROJECT_SUCCESS = createAction(
    '[Project] Remove Project Success',
);

效果:

@Effect()
removeProject$ = createEffect(() => this.actions$.pipe(
    ofType(ProjectActions.REMOVE_PROJECT),
    switchMap(props =>
        this.projects.removeProject(props.id).pipe(
           map(() => ({ type: '[Project] Remove Project Success'}),
        // have also tried
        // map(() => ProjectActions.REMOVE_PROJECT_SUCCESS())
        )
    ))
))


@Effect({ dispatch: false })
removeProjectSuccess$ = createEffect(() => this.actions$.pipe(
    ofType(ProjectActions.REMOVE_PROJECT_SUCCESS),
    tap(() => console.log('removed')),
))

删除功能:

removeProject(projectId): Observable<void> {
    return from(this.db.doc('projects/' + projectId).ref.delete());
}

1 个答案:

答案 0 :(得分:1)

这是因为您将@Effect()装饰器与createEffect()一起使用。它们在后台执行相同的操作,可能会触发无限循环。删除@Effect()注释(推荐)或createEffect()(我将其保留)。

更具体地说,createEffect()也将{dispatch: false}作为第二个参数(在您的可观察管道之后)。由于第二个选项不包含此选项,因此它只是重新分派用ofType过滤的操作,从而在遇到的无限循环中反复触发相同的操作。

如果您不想分派,这是第二种效果:

removeProjectSuccess$ = createEffect(() => this.actions$.pipe(
    ofType(ProjectActions.REMOVE_PROJECT_SUCCESS),
    tap(() => console.log('removed')),
), { dispatch: false })

在内部,装饰器和函数都向EffectsModule使用的可注入类添加注释。在这种情况下,它会产生一个不会分派的效果,而第二个效果默认情况下会分派。我希望这是有道理的。