每个函数调用Angular2 RxJS清除超时

时间:2017-03-08 11:53:47

标签: javascript angular typescript rxjs scadalts

我有一个http请求,如果用户在输入中输入至少4个字符并且每次更改其内容时都会触发(添加/删除字母)。我想添加一个超时,如果用户开始输入字符,该函数将等待1秒,直到它触发请求,以避免在用户快速键入时发出大量请求。我的尝试:

if (this.pointName.length >= 3) {
  let timer = function() {
    this.http.get(`./points.json`)
        .subscribe(res => {
            this.pointsArray = res.json();
        });
    };
clearTimeout(timer); 
setTimeout(timer,1000);

我的想法是清除每个keyup事件的超时并再次设置它。 但不幸的是,它给了我一个错误,即'类型的参数'()=> void'不能分配给'number'类型的参数。

有没有办法更有效率地做到这一点?也许使用RxJS?无论如何,我正在寻找一个有效的解决方案。提前谢谢。

HTML

 <input type="text" id="searchInput" placeholder="Point name"(keyup)="getPoints()">

3 个答案:

答案 0 :(得分:3)

为什么不使用debounceTime(500)而不是setTimeout。

https://www.learnrxjs.io/operators/filtering/debouncetime.html

答案 1 :(得分:0)

首先,您最好在RxJS中使用Debounce运算符。 您的代码中的问题是您应该将timer_id传递给clearTimeout而不是函数。

if (this.pointName.length >= 3) {
  let timer = function() {
    this.http.get(`./points.json`)
        .subscribe(res => {
            this.pointsArray = res.json();
        });
    };
let timer_id = undefined;
clearTimeout(timer_id); 
timer_id = setTimeout(timer,1000);

答案 2 :(得分:0)

试试这个:

创建RxJS主题作为组件的新成员变量

searchTerm$ = new Subject<string>();

在你的组件的ngOnInit方法中,设置你的observable,

ngOnInit() {
  this.searchTerm$
      .filter( value => value.length >= 3)
      .debounceTime(1000)
      .switchMap( val => {
         return this.http.get('./points.json')
                         .map(result => result.json());
       })
      .subscribe(result => .... // do what you want with the response );
} 

在您的HTML中,更改您的keyup事件绑定以提交输入字段的值

 <input type="text" id="searchInput" placeholder="Point name"(keyup)="getPoints(this.value)">

然后在您的组件的getPoints方法中,向您的主题$

发送一个值
getPoints(value) {
  this.subject$.next(value);
}

基本上,你创造的可观察物做了几件事:

 searchTerm$
  .filter( value => value.length >= 3)   // 1 filter out search terms that are shorter than 3 characters
  .debounceTime(1000)                    // 2. only send events after no event comes for 1 sec
  .switchMap( val => {                    // 3. convert your value to the result of your http request
     return this.http.get('./points.json')
                     .map(result => result.json());
   })
  .subscribe(result => .... // do what you want with the response );