JavaScript: Adapt synchronous code for async to support IE8?

I am working with a site with heavy data and I need to support IE8. I get some "slow script errors" in IE8, so I adapt my code to intermittently pause during loops for older browsers.

This is my current code:

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; }, 

How can I adapt calculateRatiosForData to process N rows at a time and then pause?

This will make it asynchronous, and I'm struggling to adapt my code to handle this.

Of course, all I need is support in IE8!

+6
source share
1 answer

I would say to combine the data in N rows before you get the calculation coefficients. Make the calculation coefficients a single function, i.e. this part of your program // do some calculations... then promise with Q.

After that, you can create an array of promises for each promise calculateRatiosForData(Nth row) .

After that, you can make a call to Promise.all(yourArrayOfCalculateRatioPromises) .

The problem is that you will still calculate all this data in the browser. If possible, it would be better to disable this processing on the server and use the POST request for calculations. The promise structure will still look the same.

There is also the question of whether you need these calcRatios for the rest of your script. If you don’t know if you do this, you simply encapsulate the rest of the script inside Promise.all(arrayOfPromises).then(function (result) { //rest of script} . The key element of this code is .then (function () { }) .

I would suggest using WebWorkers , but, alas, they are not supported by IE8. There are workarounds in google code , as well as here , but I can't vouch for how well these options will work.

EDIT: this will show how to keep a promise

There are basically two ways to do this.

1) You can write the calculateRatios function in the style of a node back, and then promise it with Q.

 function calculateRatios (arrayInput, callback) { //error checking if error //callback(error) //calculate the ratios algorithm then do setTimeout(callback(undefined, data), 500); } 

And then, to promise, it will look like this:

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

I personally like this way because it is compatible with other libraries of control flow without changing the original function, or you can just use the original function as it is, if it is not necessary to extend it.

2) Another way is to explicitly create a promise.

 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(); } 

NOTE. It should be noted that you will have to require a library of promises in different ways, but I leave it to you.

+5
source

All Articles