UI响应度和javascript [英] UI responsiveness and javascript

查看:24
本文介绍了UI响应度和javascript的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要在Google地图上绘制大量数据.由于数据集的大小,在绘制所有点之前,谷歌地图总是冻结几秒钟.在加载期间,我使用了一个动画旋转圈来显示它的进度.但是最终用户更喜欢看到动作.他们希望数据一步一步地绘制在地图上,而不是一次全部绘制.由于javascript不支持多线程,因此最好的方法是什么?

I have a large set of data to be plotted on google map. Because of the data set size, google map always freezes for a few seconds before all the points are plotted. I used an animated spinning circle during the loading time to show it's in progress. But end users prefer to see actions. They want data plotted on the map step by step, instead of all at a once. Since javascript doesn't support multithreading, what's the best way to approach this?

推荐答案

JavaScript引擎通过从队列中取出函数来逐一执行函数.可以通过脚本或用户操作(事件处理程序)的结果来放置函数.因此,想法是将长时间运行的任务拆分为小的短期运行的子任务,并以某种方式将其馈送到队列"中,以便它们可以与响应用户操作的功能混合在一起.
这可以通过零延迟调用window的setTimeout并将子任务作为函数传递来完成.因此,您将有机会提前执行UI事件处理程序

Javascript engine executes functions one by one by taking them from sort of a queue. Functions can be put there either by your script or as result of user's actions (event handlers). So idea is to split long-running task into small short-running subtasks and feed them into this 'queue' in the manner so they can be mixed with functions responding to user's action.
This can be done by calling window's setTimeout with zero delay and passing your sub-task as a function. Thus you will give a chance for UI event handler to be executed earlier

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原型的扩展名:

Here is extension for Array prototype:

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).要查看差异,请将批次大小设置为等于斑点数:

Usage example (you have to have div with id 'spots' somewhere in document). To see the difference, set batch size equal to number of spots:

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 ? '; ' : '');
});

这篇关于UI响应度和javascript的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆