我正在使用数据量很大的网站,我需要支持IE8。我得到一些"慢速运行的脚本" IE8中的错误,所以我调整我的代码在旧浏览器的循环期间定期暂停。
这是我目前的代码:
combineData: function(xData, yData, values) {
var combinedData = this.combineDatasets(xData, yData, values.x, values.x_val);
combinedData = this.calculateRatiosForData(combinedData);
// various other data operations, then continue to set up chart...
},
calculateRatiosForData: function(data, isSpecialDenominator, x_val_key) {
_.each(data, function(d, i) {
// do some calculations...
});
return data;
},
如何调整calculateRatiosForData
一次处理N行,然后暂停?
这将使它异步,我正在努力调整我的代码来处理这个问题。
当然,无论我做什么都需要在IE8中得到支持!
答案 0 :(得分:5)
我想说在进入计算比率之前将数据拼接成N行。使计算比率成为单一函数即。程序的这一部分// do some calculations...
然后使用Q进行宣传。
之后你可以创建一个承诺数组,每个承诺都是calculateRatiosForData(Nth row)
。
之后,您可以拨打Promise.all(yourArrayOfCalculateRatioPromises)
。
这里的问题是您仍将在浏览器上计算所有数据。如果可能,最好将该处理卸载到服务器上并使用POST
请求进行计算。承诺结构看起来仍然一样。
还有一个问题是,您是否需要为脚本的其余部分使用这些计算出的比率。如果你不好,那么你就可以将其余的脚本封装在Promise.all(arrayOfPromises).then(function (result) { //rest of script}
内。该代码的关键部分是 .then(function(){})。
我建议使用WebWorkers但是IE8不支持它们。在google code和here中找到了解决方法,但我无法保证这些选项的效果如何。
编辑:这将显示如何做出承诺
基本上有两种方法可以做到这一点。
1)您可以以节点的样式编写calculateRatios函数,然后使用Q对其进行promisify。
function calculateRatios (arrayInput, callback) {
//error checking if error
//callback(error)
//calculate the ratios algorithm then do
setTimeout(callback(undefined, data), 500);
}
然后宣传它会是这样的:
var Promise = require('q'), //however you want to do this in the browser
calculateRatiosAsync = Promise.promisify(calculateRatios);
我个人喜欢这种方式,因为它与其他控制流库兼容而不必更改原始功能,或者如果没有必要对其进行宣传,您可以按原样使用原始功能。
2)另一种方法是明确地创建一个承诺。
var Promise = require('q'),
calculateRaiosAsync = function (input) {
var d = Promise.defer();
//do your error checking if error
d.reject();
//do your calclate ratios algorithm and store the data in a variable
setTimeout(d.resolve(yourFinishedData), 500);
//return your promise
return d.promise();
}
注意:应该注意的是,您必须以不同的方式要求承诺库,但我将其留给您。