2017-02-14 75 views
0

如何在不导致浏览器挂起的情况下循环浏览非常大的对象元素?使用setTimeout循环浏览大型Javascript对象

我可以很容易环通阵列setTimeout/setInterval这样的:

var i = 0; 
var l = arr.length; 
var interval = window.setInterval(function(){ 
    var k = 100; // process 100 items on each Timeout 
    var element; 
    while(k--) { 
     if (i == l) { 
      return clearInterval(interval); 
     } 
     element = arr[i++]; 
     // ... work here ... 
    } 
}, 100); 

但什么是我的非常大的对象的选择吗?

  • 第一for(k in arr)阅读键是不是一种选择,因为这将是一个大循环,我想避免的。我不能.splice()对象,因为它不是一个数组。

目前我正在创建像这样的[{k: .., v:...},{k: .., v:...},{k: .., v:...},{k: .., v:...},{k: .., v:...},{k: .., v:...},{k: .., v:...},...]这样的阵列,但它太浪费空间了。

+0

定义“非常大的对象元素” –

+1

Object.keys()为您提供可迭代的属性名称数组。 – Shilly

+1

[Web workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)或服务器端是线程工作的好选择。但仅限于Web工作人员的现代浏览器。 – Mouser

回答

1

您可以使用Object.keys做完全相同的逻辑与对象

var i = 0; 
var keys = Object.keys(myObj); 
var l = keys.length; 
var interval = window.setInterval(function(){ 
    var k = 100; // process 100 items on each Timeout 
    var element; 
    while(k--) { 
     if (i == l) { 
      return clearInterval(interval); 
     } 
     element = myObj[ keys[i++] ]; 
     // ... work here ... 
    } 
}, 100); 

但对于按键的数以百万计,你应该寻找不同的解决方案,因为你不想遍历该许多。也许把所有东西都分成批次等等。

因此,我的问题就变成了,是否有时候你实际上需要同时在内存中的数百万个对象,因为这听起来像是一个设计问题。

+0

忽略“千变万化”我只是在开玩笑,你的答案是完美的。对于具有100000个元素的对象,Object.keys'返回小于30ms的值。实际上,我有更小的对象来处理,但我宁愿将极端情况作为测试用例。 – Peter