JavaScript:将同步代码调整为异步,以支持IE8?

Ric*_*ard 6 javascript internet-explorer-8

我正在使用数据量很大的网站,我需要支持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;
},
Run Code Online (Sandbox Code Playgroud)

如何适应一次calculateRatiosForData处理N行,然后暂停?

这将使它异步,我正在努力调整我的代码来处理这个问题.

当然,无论我做什么都需要在IE8中得到支持!

Rad*_*ith 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不支持它们.有见于变通谷歌代码,并在这里,但我不能保证这些选项将如何工作.

编辑:这将显示如何做出承诺

基本上有两种方法可以做到这一点.

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);
}
Run Code Online (Sandbox Code Playgroud)

然后宣传它看起来像这样:

var Promise = require('q'), //however you want to do this in the browser
    calculateRatiosAsync = Promise.promisify(calculateRatios);
Run Code Online (Sandbox Code Playgroud)

我个人喜欢这种方式,因为它与其他控制流库兼容而不必更改原始功能,或者如果没有必要对其进行宣传,您可以按原样使用原始功能.

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();
    }
Run Code Online (Sandbox Code Playgroud)

注意:应该注意的是,您必须以不同的方式要求承诺库,但我将其留给您.