【问题标题】:How to split the process of looping through a huge array?如何拆分遍历一个巨大数组的过程?
【发布时间】:2020-02-06 16:24:10
【问题描述】:

我有一个包含 1000 个复杂对象项的数组。

我需要循环遍历数组来运行一些函数,当数组像 100 个产品一样小时,性能似乎还可以。

但是当它达到 400 或以上的产品时,在浏览器上的性能会明显下降。

所以我想做一些事情,比如首先循环前 100 个产品,然后继续循环接下来的 100 个产品。

不确定这是个好主意吗?有没有更好的方法来处理遍历一个巨大的数组?


代码示例

实际情况是循环选择 1000 个复选框。

我有一个函数可以将li 动态附加到DOM

populateEnrichedProductList = (id, name) => {
        let html =
                `<li class="list-group-item product-item-name" productName="${name}" productId="${id}" data-desc="" data-ingredient="" data-allergens="">` +
                `${name}` +
                `<span class="error"><i class="fas fa-exclamation-triangle"></i></span>` +
                '<div class="spinner">' +
                '<div class="spinner-border text-warning" role="status">' +
                '<span class="sr-only">Loading...</span>' +
                '</div >' +
                '</div>' +
                '</li >';

                $('#selectedProductList').removeClass('hidden');    
                $('#productListUL').addClass('hidden');
                $('#selectedProductList').append(html);
    };

在这里,我遍历检查的项目,并为数组的每个项目运行函数populateEnrichedProductList

let selectedProducts = '#selectProductForm input:checked';
$(selectedProducts).each(function(){
            let pid   = $(this).attr('id'),
                pname = $(this).attr('name');

            populateEnrichedProductList(pid, pname);
        });

如前所述,当数组很小时没有问题,但是当数组有更多数据时性能会下降。

如果有人能展示一个更好地处理它以提高性能的例子,那就太好了。

【问题讨论】:

  • 这当然是一种解决方案,但是在从服务器检索数据集时过滤数据集通常是一个更好的主意。然后,您可以减少客户端上的数据权重问题。请注意,在没有看到您的实际代码的情况下,我们只能为您提供基于假设的理论解决方案。如果您想要一个可行的解决方案,我们需要查看代码以及数据示例。
  • 如果操作的长度不是一个大问题,那么您可以通过setTimeout在事件队列中间隔执行。
  • 好的,第一个命令点 - 不生成 HTML。这将非常慢,因为它使用 HTML 解析 每个元素。第二不要一个一个添加元素。您可能会多次触发reflow,这也是一项昂贵的操作。如果可能,以编程方式生成 DOM 元素并一次性添加它们。您也许可以使用文档片段。这应该会显着加快操作速度。
  • 单独说明,如果您有模板文字,则无需在每一行上连接它们。模板文字已经是多行的。

标签: javascript jquery arrays loops iteration


【解决方案1】:

您可以将阵列拆分为零件。看这段代码。这是对数组元素进行加密的示例,但您可以将此模式与您的逻辑一起使用。

const crypto = require('crypto')

const arr = new Array(200).fill('something')
function processChunk() {
  if (arr.length === 0) {
    // code executed after processing the entire array
  } else {
    console.log('processing chunk');
    // select 10 elements and remove them from the array
    const subarr = arr.splice(0, 10)
    for (const item of subarr) {
    // perform complex processing of each of the elements
      doHeavyStuff(item)
    }
    // put the function in the queue
    setImmediate(processChunk)
  }
}

processChunk()

function doHeavyStuff(item) {
  crypto.createHmac('sha256', 'secret').update(new Array(10000).fill(item).join('.')).digest('hex')
}

// This fragment is needed only to confirm that, processing a large array,
// We give the opportunity to execute another code.

let interval = setInterval(() => {
  console.log('tick!')
  if (arr.length === 0) clearInterval(interval)
}, 0)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 2013-11-06
    • 1970-01-01
    • 2016-04-11
    相关资源
    最近更新 更多