[英]JavaScript Array.filter uniqes and not block the UI
我有一個特定的用例,其中一些驗證邏輯必須在 UI 中發生(出於各種業務原因[...])。 該數組可能包含多達幾十個或多達幾十萬個項目 (1-400K)。 前端是基於 Angular 的。
第一步是檢查重復項(並將它們存儲在另一個數組中[...])。 這是通過以下方式完成的:
validateTargets(targets: string[]): ValidationResultObject[] {
let result: ValidationResultObject[];
let dups: string[] = [];
var uniques = targets.filter( (item,index) => {
if (targets.indexOf(item) === index) {
return targets.indexOf(item) === index
}
else {
dups.push(targets[index])
}
}
//other validation logic goes here
return result;
}
問題是當它針對 50K 以上的任何內容運行時,明顯的 UI 凍結。 目前,我已經在setTimeout
中的另一個函數中作為回調放在上面,以至少允許 UI 在頁面掛起時運行微調器 :)
我已經看到人們建議如何設計代碼以允許 UI 具有響應性(或至少重新繪制)的幾種方式; 但是,我的情況有點棘手,因為我要處理重復項。
我正在考慮將數組分解為塊並在setTimeout
(用於 UI)內的循環中在Array.filter
部分上方運行,但我后來無論如何都需要將這些塊與它們自己進行比較,因此它只會延長邏輯! 我覺得對員工進行試驗不太舒服,因為組織中的瀏覽器不支持這些瀏覽器。
有誰知道如何解決這個問題? 不,不可能將其移動到后端:(
問候
您可以更有效地過濾掉重復項:
let filtered = targets.reduce((result, item) => {
result[item] = 1;
return result;
}, {});
let noDuplicates = Object.keys(filtered);
這使得一次遍歷數組,並利用屬性名稱查找的內部效率超過.indexOf()
的順序搜索。 對於具有大量元素的初始數組,這應該在相對較短的時間內運行。
我從未遇到過這種情況,但我想問一下您是否在 javascript 中使用了Set
類型,因為它在內部刪除了重復項,並且比過濾JS Set vs Array更高效,如果您的瀏覽器不支持 Set,您仍然可以使用 polyfill。
您可以使用異步函數來處理此數量的數據。 當它完成時,以結果為參數調用回調以在完成后繼續正常流程。
async validateTargets(targets: string[], callback: function): {
//...Logic
callback(result)
}
此外,要刪除重復項,您可以使用
[...new Set(items)]
注意:這僅在 Items 數組僅包含原始值時才有效
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.