Angular6 rxjs 取消订阅定时器订阅 OnDestroy 不起作用?
Angular6 rxjs unsubscribing to timer subscription OnDestroy does not work?
所以我有一个计时器,我每 60 秒调用一次 api(这是一个数字标牌应用程序,所以不会有任何互动,但我希望它自动更新)
我有各种加载不同 api 调用的组件,但问题是,当我尝试取消订阅这些计时器订阅 ondestroy 时,它根本不起作用。
我进去,测试路由到2个组件来回5-6次。每次我去下一个时,这通常会导致订阅失败。
60 秒后,api 次调用与我在这两者之间切换的次数一样多。所以每次我使用其中一个组件但没有销毁它们时,我都会创建一个计时器订阅。
编辑,在下面添加了我的完整 OnInit 和 OnDestroy 代码:
ngOnInit() {
let mainTimer = timer(0, 60000);
this.dataSourceSubscription = mainTimer.subscribe(t => {
this.service.getSection3();
this.dataSourceSubscription = this.section3.subscribe(data => {
let countAccepted = data => {
for (let i = 0; i < data.length; i++) {
if (
data[i].DeliveryStatus == "Accepted" &&
data[i].BookingId == "0"
) {
this.multidropAccepted++;
}
}
};
let countDepartedSite = data => {
for (let i = 0; i < data.length; i++) {
if (
data[i].DeliveryStatus == "Departed Site" &&
data[i].BookingId == "0"
) {
this.multidropDepartedSite++;
}
}
};
let countPending = data => {
for (let i = 0; i < data.length; i++) {
if (
data[i].DeliveryStatus == "Pending" &&
data[i].BookingId == "0"
) {
this.multidropPending++;
}
}
};
let countOnSite = data => {
for (let i = 0; i < data.length; i++) {
if (
data[i].DeliveryStatus == "On Site" &&
data[i].BookingId == "0"
) {
this.multidropOnSite++;
}
}
};
let countTurnedAway = data => {
for (let i = 0; i < data.length; i++) {
if (
data[i].DeliveryStatus == "Turned Away" &&
data[i].BookingId == "0"
) {
this.multidropTurnedAway++;
}
}
};
(this.dataSource = new MatTableDataSource(
data.filter(
(value, index, array) =>
!array.filter(
(v, i) => JSON.stringify(value) == JSON.stringify(v) && i < index
).length
)
)),
(this.dataSource.sort = this.sort),
(this.dataSource.paginator = this.paginator),
this.multidropAccepted = 0;
this.multidropDepartedSite = 0;
this.multidropPending = 0;
this.multidropOnSite = 0;
this.multidropTurnedAway = 0;
countAccepted(data),
countDepartedSite(data),
countPending(data),
countOnSite(data),
countTurnedAway(data),
this.totalDeliveries = data.length;
});
this.lastUpdated.subscribe(data => {
console.log(data);
})
})
let pageTimer = timer(10000, 10000);
this.pageSubscription = pageTimer.subscribe(t => {
if (
this.dataSource.paginator._pageIndex ==
this.dataSource.paginator.getNumberOfPages()
) {
this.dataSource.paginator.firstPage();
} else {
this.dataSource.paginator.nextPage();
}
});
}
ngOnDestroy() {
this.dataSourceSubscription.unsubscribe();
this.pageSubscription.unsubscribe();
}
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
因此,根据您在问题中的描述,一般来说,我认为您订阅和取消订阅可观察对象的方式没有任何问题。
这意味着错误一定是愚蠢的。
要进一步调查,请检查:
你的代码有错字吗?
ngOnDestroy()
真的被执行了吗? - 在那里放一个控制台日志,看看当你离开当前页面时它是否真的被调用。如果不是,即使页面似乎已更改,您也可能保持相同的路由规则。
订阅被覆盖,因此它不再指向计时器。当你销毁(取消订阅)它时,它实际上是取消订阅内部可观察对象,而不是定时器可观察对象。
this.dataSourceSubscription = mainTimer.subscribe(t => {
this.dataSourceSubscription = this.section3.subscribe(data => {});
});
所以我有一个计时器,我每 60 秒调用一次 api(这是一个数字标牌应用程序,所以不会有任何互动,但我希望它自动更新)
我有各种加载不同 api 调用的组件,但问题是,当我尝试取消订阅这些计时器订阅 ondestroy 时,它根本不起作用。
我进去,测试路由到2个组件来回5-6次。每次我去下一个时,这通常会导致订阅失败。
60 秒后,api 次调用与我在这两者之间切换的次数一样多。所以每次我使用其中一个组件但没有销毁它们时,我都会创建一个计时器订阅。
编辑,在下面添加了我的完整 OnInit 和 OnDestroy 代码:
ngOnInit() {
let mainTimer = timer(0, 60000);
this.dataSourceSubscription = mainTimer.subscribe(t => {
this.service.getSection3();
this.dataSourceSubscription = this.section3.subscribe(data => {
let countAccepted = data => {
for (let i = 0; i < data.length; i++) {
if (
data[i].DeliveryStatus == "Accepted" &&
data[i].BookingId == "0"
) {
this.multidropAccepted++;
}
}
};
let countDepartedSite = data => {
for (let i = 0; i < data.length; i++) {
if (
data[i].DeliveryStatus == "Departed Site" &&
data[i].BookingId == "0"
) {
this.multidropDepartedSite++;
}
}
};
let countPending = data => {
for (let i = 0; i < data.length; i++) {
if (
data[i].DeliveryStatus == "Pending" &&
data[i].BookingId == "0"
) {
this.multidropPending++;
}
}
};
let countOnSite = data => {
for (let i = 0; i < data.length; i++) {
if (
data[i].DeliveryStatus == "On Site" &&
data[i].BookingId == "0"
) {
this.multidropOnSite++;
}
}
};
let countTurnedAway = data => {
for (let i = 0; i < data.length; i++) {
if (
data[i].DeliveryStatus == "Turned Away" &&
data[i].BookingId == "0"
) {
this.multidropTurnedAway++;
}
}
};
(this.dataSource = new MatTableDataSource(
data.filter(
(value, index, array) =>
!array.filter(
(v, i) => JSON.stringify(value) == JSON.stringify(v) && i < index
).length
)
)),
(this.dataSource.sort = this.sort),
(this.dataSource.paginator = this.paginator),
this.multidropAccepted = 0;
this.multidropDepartedSite = 0;
this.multidropPending = 0;
this.multidropOnSite = 0;
this.multidropTurnedAway = 0;
countAccepted(data),
countDepartedSite(data),
countPending(data),
countOnSite(data),
countTurnedAway(data),
this.totalDeliveries = data.length;
});
this.lastUpdated.subscribe(data => {
console.log(data);
})
})
let pageTimer = timer(10000, 10000);
this.pageSubscription = pageTimer.subscribe(t => {
if (
this.dataSource.paginator._pageIndex ==
this.dataSource.paginator.getNumberOfPages()
) {
this.dataSource.paginator.firstPage();
} else {
this.dataSource.paginator.nextPage();
}
});
}
ngOnDestroy() {
this.dataSourceSubscription.unsubscribe();
this.pageSubscription.unsubscribe();
}
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
因此,根据您在问题中的描述,一般来说,我认为您订阅和取消订阅可观察对象的方式没有任何问题。
这意味着错误一定是愚蠢的。
要进一步调查,请检查:
你的代码有错字吗?
ngOnDestroy()
真的被执行了吗? - 在那里放一个控制台日志,看看当你离开当前页面时它是否真的被调用。如果不是,即使页面似乎已更改,您也可能保持相同的路由规则。
订阅被覆盖,因此它不再指向计时器。当你销毁(取消订阅)它时,它实际上是取消订阅内部可观察对象,而不是定时器可观察对象。
this.dataSourceSubscription = mainTimer.subscribe(t => {
this.dataSourceSubscription = this.section3.subscribe(data => {});
});