使用JS/JQuery异步迭代大型对象数组
我有一个从JSON文件读取的大型(约10,000项)对象对象,并将其存储为局部变量,格式如下:
{
"some_uuid_1" : {"code":"some_code_1", "name":"asdf"},
"some_uuid_2" : {"code":"some_code_2", "name":"qwer"},
...
"some_uuid_n" : {"code":"some_code_n", "name":"zxcv"}
}
我想遍历整个主对象,将每个元素的name
属性与某个变量checkName
进行比较,如果匹配,则将元素的code
属性附加到DOM元素,如下所示:
function myFilter(checkName)
{
var myArray = Object.values(myObj);
for (var i = 0; i < myArray.length; i++)
{
if (myArray[i]["name"] == checkName)
{
$("#someElement").append(`${myArray[i]["code"]} <br />`);
}
}
}
但是,由于对象的大小相当大,我希望异步运行该函数,这样它就不会在浏览器运行时冻结它。我不介意在其他代码运行时DOM元素#someElement
在后台缓慢填充。
如何使用JavaScript和/或JQuery完成此操作?
解决方案
这里有个小帮手可能会有帮助:
function asyncForEach(arr, cb, done) {
(function next(i) {
if(i >= arr.length) {
if(done) done();
return;
}
cb(arr[i], i, arr);
setTimeout(next, 0, i + 1); // a small trick to defer actions
})(0);
}
或者要对其进行优化,您可以将结果分块,大约每1000次迭代才产生结果:
function asyncForEach(arr, cb, done) {
(function next(i) {
if(i >= arr.length) {
if(done) done();
return;
}
let stop = i + 1000;
setTimeout(next, 0, stop); // a small trick to defer actions
while(i < arr.length && i < stop)
cb(arr[i], i++, arr);
})(0);
}
在您的案例中可以这样使用:
asyncForEach(myArray, function(el) {
if (el.name === checkName){
$("#someElement").append(`${el.code} <br />`);
}
});
但是,这里可能最慢的部分是附加到DOM。如果您不想有"实时进度",最好将DOM更新批处理到一个调用:
let result = "";
asyncForEach(myArray, function(el) {
if (el.name === checkName){
result += `${el.code} <br />`;
}
}, function() {
$("#someElement").append(result);
});
然后即使是同步变种也可能足够快:
let result = "";
for(const el of myArray) {
if(el.name === checkName)
result += `${el.code} <br />`;
}
$("#someElement").append(result);
相关文章