我想在函数运行后延迟它,这样它就不能在这段时间内再次运行了。
一个接近它的例子:
ngOnInit() {
setInterval(() => this.functionWithTimeLimit(), 500);
}
functionWithTimeLimit() {
if(allowedToRun){
console.log('Run me every 2 seconds at most');
allowedToRun = false;
setTimeout(() => allowedToRun = true, 2000); // Allow to execute this function again after two seconds
}
}
但我相信有一种更好的方法可以用rxjs实现这一点。我怎么能那样做?
有多种方法可以做到这一点。
一种方法是创建一个RxJSSubject
,并路由函数调用以从中发出通知。在订阅此可观察对象时,您可以使用RxJSthrottleTime
运算符在指定的时间内忽略后续的发射。
尝试以下
控制器
import { Subject } from 'rxjs';
import { throttleTime, takeUntil } from 'rxjs/operators';
export class AppComponent implements OnInit, OnDestroy {
completed$ = new Subject<any>();
trigger$ = new Subject<any>();
constructor() { }
functionWithTimeLimit() {
console.log('called functionWithTimeLimit');
}
ngOnInit() {
this.trigger$.pipe(
throttleTime(2000), // <-- ignore notifications for 2s after an emission
takeUntil(this.completed$) // <-- use to close the subscription
).subscribe(this.functionWithTimeLimit.bind(this));
}
ngOnDestroy() {
this.completed$.next(); // <-- close impending subscriptions
}
}
模板
<button (mouseup)="trigger$.next()">Trigger function</button>
工作示例:Stacklitz
在上面的例子中,假设最初按下按钮应该直接触发该功能。但现在,当按下按钮并触发订阅中的函数时,我们会发出可观察到的信息。
更新:throttleTime
和debounceTime
之间的差异
throttleTime
将在单个通知后暂停后续通知一段固定时间。
var { fromEvent } = rxjs;
var { throttleTime, map } = rxjs.operators;
var inputBox = document.getElementById('search');
var displayBox = document.getElementById('display');
fromEvent(inputBox, 'keyup').pipe(
map(event => event.currentTarget.value),
throttleTime(2000),
).subscribe(value => displayBox.innerHTML = value);
<script src="https://unpkg.com/rxjs@6.4.0/bundles/rxjs.umd.min.js"></script>
Keep on typing. It will render the value continuously every 2 sec.<br><br>
<input type="text" id="search" />
<p id="display"></p>
debounceTime
将在每次通知后暂停后续通知一段固定时间。
var { fromEvent } = rxjs;
var { debounceTime, map } = rxjs.operators;
var inputBox = document.getElementById('search');
var displayBox = document.getElementById('display');
fromEvent(inputBox, 'keyup').pipe(
map(event => event.currentTarget.value),
debounceTime(2000),
).subscribe(value => displayBox.innerHTML = value);
<script src="https://unpkg.com/rxjs@6.4.0/bundles/rxjs.umd.min.js"></script>
Keep on typing. It'll render only after 2 seconds after the typing stops.<br><br>
<input type="text" id="search" />
<p id="display"></p>
您可以使用interval和debounceTime来更好地处理这种情况。
适当时(可能在ngOnDestroy
上(注意unsubscribe
我有一个工作的例子,不确定这是否是你的情况,但你可以玩它。StackBlitz