Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 如何修复ngrx存储中的订阅泄漏_Angular_Ngrx_Ngrx Store - Fatal编程技术网

Angular 如何修复ngrx存储中的订阅泄漏

Angular 如何修复ngrx存储中的订阅泄漏,angular,ngrx,ngrx-store,Angular,Ngrx,Ngrx Store,我有一个ponyracer应用程序,它实现了ngrx商店。非常基本的功能:开始比赛,添加小马,删除小马,分数表。当我移除或添加小马时,问题就来了——基本上,这个功能是指创建或销毁小马组件。因此,由于某种原因,任何添加的小马都会存储在某个地方,即使在销毁了一个组件之后,应用程序仍然可以访问所有添加和删除的小马,并对它们进行迭代,例如,当我只需要查看现有小马的分数时,但会显示所有(甚至以前删除的)小马 我使用store.select.pipe(…).subscribe(),不需要使用onDestro

我有一个ponyracer应用程序,它实现了ngrx商店。非常基本的功能:开始比赛,添加小马,删除小马,分数表。当我移除或添加小马时,问题就来了——基本上,这个功能是指创建或销毁小马组件。因此,由于某种原因,任何添加的小马都会存储在某个地方,即使在销毁了一个组件之后,应用程序仍然可以访问所有添加和删除的小马,并对它们进行迭代,例如,当我只需要查看现有小马的分数时,但会显示所有(甚至以前删除的)小马

我使用store.select.pipe(…).subscribe(),不需要使用onDestroy和unsubscribe()

组件

export class RacesComponent implements OnInit {
    racesState: Observable<fromPonyRacer.State>;

    constructor(private store: Store<fromApp.AppState>) { }

    ngOnInit() {
        this.racesState = this.store.select("raceList");
        this.racesState.subscribe()
    }
}
export class RaceComponent implements OnInit {
    @Input() race: RaceModel;
    @Input() index: number;
    racesState: Observable<fromPonyRacer.State>;

    constructor(private store: Store<fromApp.AppState>) { }

    ngOnInit() {
    this.racesState = this.store.select("raceList");
    this.racesState.pipe(
        tap(races => {
            if(races.raceStatus) this.movePony();
        })
    )
    .subscribe()
    }
}
但是这个动作也会被分派给移除的小马,它们也会到达store.currentRaces,并显示在分数表中。我不知道这些被移除的小马是从哪里来的。因为state.races总是真实和正确的(根据redux开发工具),races.component使用state.races为每匹小马呈现视图,并且总是正确和新鲜的

movePony() {
    some code for moving a pony
      if(ponyReachedFinish) {
      this.store.dispatch(new PonyRacerActions.StopRace({name: this.race.name, place, points})
    }
}
如果需要更多详细信息,您可以在此处找到完整的代码:

更新:问题已解决。正如我最初设想的那样,问题是由于订阅泄漏而发生的。我应用了OnDestroy,在这个方法中应用了一行代码
this.subscription.unsubscripte()

在reducer中,删除小马时,直接改变状态,而不是返回新的不可变状态。尝试应用以下更改:

case PonyRacerActions.DELETE_PONY:
            return {
                ...state,
                races: state.races.filter(race => race != action.payload),
                currentRaces: []
            }

在reducer中,当删除小马时,直接改变状态,而不是返回新的不可变状态。尝试应用以下更改:

case PonyRacerActions.DELETE_PONY:
            return {
                ...state,
                races: state.races.filter(race => race != action.payload),
                currentRaces: []
            }

如果在热观测上使用
subscribe
,为什么
不需要使用onDestroy和unsubscribe()
?这应该是强制性的。我是第二个@trichetriche。如果您要订阅存储区中的可观察对象,则需要使用
异步
管道进行订阅,或者在组件中显式调用
.unsubscribe()
。@Trichetrich流是热的这一事实与此问题并不相关,而流是无限的。是的,尽管订阅Observable是一种糟糕的做法,但它肯定不是bug的原因。在移除小马的地方张贴减速器的代码。@Jota.Toledo无论异步管道订阅可观察对象,还是在组件中执行,都不会更改发出的值。很明显,他的错误在他的还原器中的某个地方,而还原器实际上决定了他的应用程序的状态。如果你在热观测上使用
subscribe
,为什么
没有必要使用onDestroy和unsubscribe()
?这应该是强制性的。我是第二个@trichetriche。如果您要订阅存储区中的可观察对象,则需要使用
异步
管道进行订阅,或者在组件中显式调用
.unsubscribe()
。@Trichetrich流是热的这一事实与此问题并不相关,而流是无限的。是的,尽管订阅Observable是一种糟糕的做法,但它肯定不是bug的原因。在移除小马的地方张贴减速器的代码。@Jota.Toledo无论异步管道订阅可观察对象,还是在组件中执行,都不会更改发出的值。很明显,他的错误在他的还原程序中的某个地方,而还原程序实际上决定了他的应用程序的状态。尝试了这种方法更新还原程序,但仍然面临相同的问题。删除小马->开始比赛->仍然可以在分数表中看到删除的小马尝试了这种方式更新减速器,但仍然面临相同的问题。删除小马->开始比赛->仍然可以在分数表中看到删除的小马
movePony() {
    some code for moving a pony
      if(ponyReachedFinish) {
      this.store.dispatch(new PonyRacerActions.StopRace({name: this.race.name, place, points})
    }
}
case PonyRacerActions.DELETE_PONY:
            return {
                ...state,
                races: state.races.filter(race => race != action.payload),
                currentRaces: []
            }