我有一个this方法,在滚动表时会被多次调用:
setViewportRange(firstRow: number, lastRow: number): void {
this.getViewport(firstRow, lastRow).subscribe(message => {
console.log(message);
});
}
我没有setViewportRange方法调用的控制权,但是我需要去抖动,所以我用help lodash的去抖动函数创建了这个debouncedGetViewport方法:
setViewportRange(firstRow: number, lastRow: number): void {
this.debouncedGetViewport(firstRow, lastRow);
}
debouncedGetViewport = debounce((firstRow, lastRow) => {
return this.getViewport(firstRow, lastRow).subscribe(message => {
console.log(message);
});
}, 1000);
它起作用了!但是一个同事问我为什么不用RxJs去反跳。所以我试着用RxJs去反跳,但是我不能让它起作用。无论传递哪个值,去反跳时间都没有作用!你能帮我理解为什么它不起作用吗?我想我误解了什么。
setViewportRange(firstRow: number, lastRow: number): void {
this.debouncedGetViewport(firstRow, lastRow);
}
debouncedGetViewport = (firstRow, lastRow) => {
return this.getViewport(firstRow, lastRow)
.pipe(debounceTime(1000))
.subscribe(message => {
console.log(message);
});
};
谢谢大家!
1条答案
按热度按时间i7uq4tfw1#
首先不要忘记取消订阅!
首先,从内存泄漏的Angular 或在调用
setViewportRange
时多次订阅this.getViewport
时的奇怪行为进行确认。您不知道this.getViewport
后面发生了什么。getViewport.subscribe的回调可能会被多次调用。始终取消订阅是一个好习惯。如何取消订阅?有几种方法可以取消订阅一个观测对象,但在您的情况下,您可以只使用
take
操作符。以下是您应该取消订阅的一些资源:
Subscription
您没有准确描述什么不起作用!
我根据您的示例问题创建了一个playground,我想我知道您的意思:“你能帮我理解为什么这是行不通的”。
我猜console.log被调用了,但是
debounceTime
没有任何效果,对吗?请确保下次您在问题描述中准确解释了什么不起作用。可能会发生这样的情况,您将得到一个负分。为什么你的debounceTime不工作?
我认为Nuno Sousa给出了一个很好的堆栈溢出解释,说明了为什么您的
debounceTime
示例不起作用!考虑一下你的逻辑。你将为每个onChanges创建一个终结的观察者。它不会去抖动,因为观察者已经终结了,去抖动是为了防止发出一个观察者,以防另一个观察者出现。所以它需要至少两个(或更多)发射才是合理的,如果观察者是在回调中创建的,那就不可能发生。
看起来你正在用
this.getViewport
创建一个finalized(完成的)观察对象,它在发出第一个值后立即完成,这就是debounceTime
在这里没有效果的原因。***提示:***
take(1)
在观察结果到达时已经完成时没有任何效果,但最佳实践是始终取消订阅订阅。您需要不同的解决方案!
我已经为前面的代码创建了一个Stackblitz示例!
我们的不同解决方案中发生了什么?
在我们的新解决方案中,我们没有使用一个最终化的观察对象,因为我们使用了一个
Subject (rows$)
,而Subject不能像getViewport
那样完成它自己。我们必须显式地自己完成它。我们可以在takeUntil操作符中看到这一点。只有当组件被销毁时,所以当ngOnDestroy
被调用的时候,我们告诉我们的行$ observable完成它自己,最后但同样重要的是,我们用switchMap
从getViewport
得到我们的值,就是这样。你可能想知道
debounceTime
和switchMap
的顺序在这里是否有区别。这取决于!如果this.getViewport
是一个昂贵的操作,那么就把它放在debounceTime
之后,如果它非常便宜,那么顺序就不重要了。