如何停止array.filter()函数

时间:2017-12-11 15:05:38

标签: javascript arrays angular typescript

使用自定义搜索过滤器

HTML

 <input type="text" pInputText class="ui-widget ui-text" [(ngModel)]
 ="gloablFilterValue" (ngModelChange)="splitCustomFilter()" placeholder="Find" />

我在搜索框

上使用ngModelChange()个事件

&#13;
&#13;
globalSearch(realData, searchText, columns) {
        searchText = searchText.toLowerCase();
        return realData.filter(function (o) {
            return columns.some(function (k) {
                return o[k].toString().toLowerCase().indexOf(searchText) !== -1;
            });
        });
    }

    splitCustomFilter() {
    let columns =  
   ['PartNoCompleteWheel', 'DescriptionCompleteWheel', 'PartNoTyre', 'DescriptionTyre', 'PartNoRim', 'DescriptionRim','DeletedDateFromKDPStr', 'DateFromKDPStr', 'Status'];
   this.tyreAndRimList = this.globalSearch(this.tyreAndRimList, this.gloablFilterValue, columns); 
    }
&#13;
&#13;
&#13;

this.tyreAndRimList变量中提到的列的column值列表。

问题

过滤器工作正常!但主要问题是过滤器性能非常差,而记录数量很大(每列超过100行)

:当

如果输入单个字符(例如a),则过滤器工作正常。但是当我不断地输入字符时,浏览器就会挂起。原因是过滤器已经过滤了过滤器盒上的每一个类型(因为我正在使用ngModelChange()// onchange()事件)

我想要什么

如果用户在搜索框上连续输入,我想停止过滤。一旦用户停止输入,那么我只需要开始过滤。

我做了什么

我尝试使用setTimeout()处理此问题。但它只是等待过滤器调用一秒钟。如果用户连续输入2或3个字符,它就可以正常工作。但是如果用户键入超过7或8或更高的字符,它将继续挂起浏览器。因为许多过滤器回调都在同一时间进行处理。

 setTimeout(() => //code of filtering ,1000);

问题

如何在用户连续输入值时停止过滤,并在用户停止输入后开始过滤?

我在angular-2和打字稿中工作。但是这个问题与angularjsangularJavaScripttypescript无关,因为我想要一个想法而不是解决方案。所以我会为这个问题添加所有标签。不要删除它。感谢

4 个答案:

答案 0 :(得分:2)

去抖动功能。看看下划线是如何做到的:Function Debouncing with Underscore.js

然后你会生成你的函数的去抖版本:

var globalSearchDebounced = _.debounce(globalSearch, 100, false);

只有在用户停止输入至少一秒后才会调用。

答案 1 :(得分:1)

无法中断Array.filter方法。根据你的需要,你可以这样处理:

let timerId = null

function handleChange() {
  if(timerId) {
    clearTimeout(timerId)
  }

  timerId = setTimeout(() => /* Array.filter(...) */, 1000)
}

<强>解释

拥有一个包含timerId函数返回的setTimeout的变量。每次模型更改时,都会调用handleChange函数(在本例中)。该函数检查包含timerId的变量是否已设置且包含timerId,当变量包含timerId时,将调用clearTimeout函数以清除先前的超时之后,handleChange创建一个新的超时,并将timerId(从setTimeout函数返回)分配给变量。

答案 2 :(得分:1)

如果没有下划线,并且没有Timeout(顺便触发整个Angular生命周期),您可以使用具有异步管道和去抖动的Observable。

在您的全球搜索功能中:

return Observable.of(/* filter here and return the filtered array */).debounceTime(1000)

在你的清单中(我猜想必须在某处)

<list-item *ngFor="let x of myFilteredResults | async">...</list-item>

答案 3 :(得分:0)

我已使用SubjectdebounceTime完成了该操作。

private subject = new Subject<string>()
ngOnInit() {
        this.subject.debounceTime(300).subscribe(inputText => {
        this.gloablFilterValue = inputText;
        this.splitCustomFilter();   // filter method  
        });    
    }

现在,当我使用change事件更改this.gloablFilterValue对象中的值时。它只是等待事件结束。