swi*_*ure 4 javascript user-interface
我有一大堆数据要在谷歌地图上绘制.由于数据集大小,谷歌地图总是在绘制所有点之前冻结几秒钟.我在加载时使用了一个动画旋转圆圈来显示它正在进行中.但最终用户更愿意看到行动.他们希望逐步在地图上绘制数据,而不是一次性绘制所有数据.由于javascript不支持多线程,最好的方法是什么?
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();
Run Code Online (Sandbox Code Playgroud)
这是Array原型的扩展:
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();
};
Run Code Online (Sandbox Code Playgroud)
用法示例(您必须在文档中的某处具有id为'spot'的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 ? '; ' : '');
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
960 次 |
| 最近记录: |