我正在研究客户端脚本,并且需要进行繁重的计算,例如在数组中推送大量对象,它会导致JavaScript停止响应并且浏览器挂起并发出警报:
是否有处理这些计算的最佳实践或设计模式,我搜索并找到许多不同的方法来处理这些情况,但解决方案很难实现,因此我需要最佳实践并且易于理解?
(我正在编写代码,但我需要一个跨浏览器的通用解决方案,即多线程等)
示例代码(系列包含数千个对象):
for (var series = 0; series < chartObj.masterChart.series.length; series++) {
var detailData = [];
jQuery.each(chartObj.masterChart.series[series].data, function (i, point) {
if (point.x >= chartObj.RangeSelectedMinValue && point.x <= chartObj.RangeSelectedMaxValue) {
detailData.push({
x: point.x,
y: point.y
});
}
});
chartObj.detailChart.series[series].setData(detailData);
}
答案 0 :(得分:5)
好的,看看你的代码,你可以优化一些东西:
var s = chartObj.masterChart.series, // #1
sLength = s.length, // #2
chartMin = chartObj.RangeSelectedMinValue,
chartMax = chartObj.RangeSelectedMaxValue;
for (var series = 0; series < sLength; series++) {
var detailData = [],
data = s[series].data, // #3
length = data.length; // #2
for(var i = 0; i < length; i++){ // #4
var point = data[i];
if (point.x >= chartMin && point.x <= chartMax) {
detailData.push({
x: point.x,
y: point.y
});
}
}
chartObj.detailChart.series[series].setData(detailData);
}
s[series].data
分配给临时变量。这提供了一个指向数据的直接指针,而不必每次迭代循环访问s[series].data
。与#1相同的原则我不是说这个编辑会创造奇迹,但它应该会减少负荷。
答案 1 :(得分:2)
您应该使用WebWorkers
他们是really supported 它们是javascript中的真正线程,因为它们产生了真正的操作系统线程!
main.js
var heavy_process = new Worker('heavy_process.js');
heavy_process.addEventListener('message', function(e) {
// Log the workers message.
console.log(e.data);
}, false);
heavy_process.postMessage();
for (var series = 0; series < chartObj.masterChart.series.length; series++) {
var detailData = [];
jQuery.each(chartObj.masterChart.series[series].data, function (i, point) {
if (point.x >= chartObj.RangeSelectedMinValue && point.x <= chartObj.RangeSelectedMaxValue) {
detailData.push({
x: point.x,
y: point.y
});
}
});
chartObj.detailChart.series[series].setData(detailData);
// you should use self.postMessage here !!!
}
答案 2 :(得分:1)
您可以使用超时将其拆分为不同的“线程”。像这样:
var counter;
function longRun(start) {
counter = 0;
for (var i = start; i < 3000; i++) {
counter++;
console.log(i);
if (counter > 99) {
setTimeout(function() {
longRun(i+1)
}, 0);
console.log('counter at: ' + i + ' start fake "thread"');
return;
}
}
alert('Done!');
}
longRun(0);
我想它会阻止警告,但我不知道它是多么健全。