UI 响应能力和 JavaScript

2023-12-05

我有大量数据要绘制在谷歌地图上。由于数据集大小的原因,谷歌地图在绘制所有点之前总是会冻结几秒钟。我在加载期间使用了一个动画旋转圆圈来显示它正在进行中。但最终用户更喜欢看到操作。他们希望将数据逐步绘制在地图上,而不是一次全部绘制。由于 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();

这是数组原型的扩展:

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 为“spots”的 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 ? '; ' : '');
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UI 响应能力和 JavaScript 的相关文章

随机推荐