如何停止 array.filter() 函数

how to stop array.filter() function

我正在使用自定义搜索过滤器

HtML

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

我在搜索框上使用 ngModelChange() 事件


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); 
    }

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

问题

过滤器运行良好!但主要问题是过滤性能很差,而记录数很大(每列超过 100 行)

如果输入单个字符(如 a),过滤器工作正常。但是当我连续输入字符时,浏览器挂起。原因是过滤器一直在触发过滤器框中的每个输入(因为我正在使用 ngModelChange()// onchange() 事件)

我想要的

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

我做了什么

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

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

问题

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

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

去抖函数。在这里查看下划线是如何做到的:Function Debouncing with Underscore.js

然后您将生成函数的去抖动版本,如下所示:

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

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

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

let timerId = null

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

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

说明

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

没有下划线,也没有超时(顺便说一句,这将触发整个 Angular 生命周期),您可以使用带有异步管道和去抖动的 Observable。

在您的全局搜索功能中:

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

在你的列表中(我猜这一定是某个地方)

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

我已经用SubjectdebounceTime完成了。

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

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