2009-06-05 56 views
4

我有一大组数据被绘制在谷歌地图上。由于数据集的大小,谷歌地图总是冻结几秒钟,然后绘制所有点。在加载时间内,我使用了一个动画旋转圈来显示它正在进行中。但最终用户更喜欢看到行动。他们希望一步一步地在地图上绘制数据,而不是一次。由于JavaScript不支持多线程,最好的方法是什么?用户界面响应和javascript

+0

我还没有搞砸Google地图。这个数字有多少在你的控制之下,其中有多少是在Google的? – Nosredna 2009-06-05 21:21:14

回答

7

JavaScript引擎通过从一个队列中取出它们来逐个执行函数。函数可以通过脚本或用户操作(事件处理程序)的结果放在那里。因此,想法是将长时间运行的任务分解为小的短时间运行的子任务,并以这种方式将它们馈送到此“队列”中,以便它们可以与响应用户操作的功能混合使用。
这可以通过调用窗口的setTimeout和零延迟并将子任务作为函数传递来完成。因此,你会给一个机会要执行UI事件处理较早

function plotSpot(spot) { 
    // adding spots to map 
}; 
var spots = [1,2,3,4,5,6,7,8,9,10,11,12]; 
var plotSpotsBatch; 
plotSpotsBatch = function() { 
    var spotsInBatch = 10; 
    while(spots.length > 0 && spotsInBatch--) { 
     var spot = spots.shift(); 
     plotSpot(spot); 
    } 
    if (spots.length > 0) { 
     setTimeout(plotSpotsBatch, 0); 
    } 
}; 
plotSpotsBatch(); 

这里是扩展阵列原型:

Array.prototype.forEachInBatches = function(batchSize, func) { 
    var arr = this; 
    var i = 0; 
    var doer; 
    doer = function() { 
     setTimeout(function() { 
      for (var stopBatch = i + batchSize; i < stopBatch && i < arr.length; i++) { 
       func(arr[i], i); 
      } 
      if (i < arr.length) { 
       doer(); 
      } 
     }, 0); 
    }; 
    doer(); 
}; 

使用实例(你必须有ID为“点”的地方DIV中文件)。要看到差距,设定批量大小等于点的数量:

var spots = []; 
for (var i = 0; i < 10000; i++) { 
    spots.push('{x: ' + Math.ceil(Math.random() * 180) + ', y: ' + Math.ceil(Math.random() * 180) + '}'); 
} 
spots.forEachInBatches(10, function(spot, i) { 
    document.getElementById('spots').innerHTML += spot + (i < spots.length ? '; ' : ''); 
}); 
4

你可以批量绘制它们,每个之间有短暂的延迟(setTimeout)?

4

Javascript可能不会正常支持多个线程,但您可以达到该效果。

function spawnThread(func, params){ 
    window.setTimeout(
     (function(f, p){ 
     return function(){ 
      f.call(p); 
     } 
    )(func, params), 0 
    ) 
} 

用这种方法当然会,上线的成功被检查的主要问题,我想你可以使用全局变量或类似的东西管理这个,不会是一个很好的解决方案,但它会工作。

+2

设置超时不会创建任何新线程(JavaScript始终在单个线程中运行在收藏器中)。相反,使用这种技术,你可以将一项长任务分配给较小的任务,并且在执行前一个任务并且浏览器做出简要说明之前,推迟执行。 – 2009-06-05 21:31:44

+0

setTimeout实际上并不会生成线程。 setTimeout延迟执行,直到至少达到指定的毫秒数。 – 2009-06-05 21:32:13

1

类似于musicfreak说,但不需要齿轮,是Javascript web workers。但是现在只在最新版本的浏览器中实现。