javascript - 不允许函数在执行后一段时间内继续执行

标签 javascript angular rxjs observable

我想在函数运行后延迟它,这样它就不能在这段时间内再次运行。

实现它的示例:

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 来做到这一点。我怎样才能做到这一点?

最佳答案

有多种方法可以做到这一点。

一种方法是创建一个 RxJS Subject并路由函数调用以从中发出通知。在订阅这个可观察的内容中,您可以使用 RxJS throttleTime运算符(operator)在指定的时间内忽略后续排放。

尝试以下操作

Controller

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>

工作示例:Stackblitz

在上面的示例中,假设最初按下按钮应该直接触发该功能。但现在我们在按下按钮时发出可观察的结果并触发其订阅中的函数。

更新:throttleTimedebounceTime 之间的差异

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/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dfada7b5ac9fe9f1ebf1ef" rel="noreferrer noopener nofollow">[email protected]</a>/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/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0d7f75677e4d3b2339233d" rel="noreferrer noopener nofollow">[email protected]</a>/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>

关于javascript - 不允许函数在执行后一段时间内继续执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63189239/

相关文章:

javascript - 如何在 Javascript 或 JqueryUI 中将 <line> 拖到 <rect> 内?

javascript - Angular无限循环调用函数

angular - 共享混合移动应用程序和桌面 Web 应用程序的代码

javascript - 为什么 javascript 不能在 Firefox 中运行

javascript - 如何使用 JavaScript 访问 JSON 数据中嵌套数组中的特定元素?

angular - 无效管道参数 : '[object Object]' for pipe 'AsyncPipe' Angular 6 and FIrebase

javascript - 更好的 Observable typescript 模式 if x of Observable<X> else y of Observable<Y>

Angular2 - http.post(...).map 不是函数

包含在 HTML 页面中的 Javascript D3 树可视化

javascript - 用于仪表板应用程序的 Angular 7 多个路由器 socket