I am working with a data-heavy website and I need to support IE8. I am getting some "slow-running script" errors in IE8, so I am adapting my code to pause periodically 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, then pause?
This will make it asynchronous, and I'm struggling to adapt my code to handle this.
Whatever I do needs to be supported in IE8, of course!
JavaScript is a single-threaded, non-blocking, asynchronous, concurrent programming language with lots of flexibility.
JavaScript provides three methods of handling asynchronous code: callbacks, which allow you to provide functions to call once the asynchronous method has finished running; promises, which allow you to chain methods together; and async/await keywords, which are just some syntactic sugar over promises.
Internet Explorer IE browser version 6 to 11 doesn't supports JAVASCRIPT Async functions.
I would say to splice the data into N rows before you get into calculate ratios. Make the calculate ratios a single function ie. this part of your program // do some calculations...
then promisify it using Q.
After that you can create an array of promises each promise being calculateRatiosForData(Nth row)
.
After that you can make a call to Promise.all(yourArrayOfCalculateRatioPromises)
.
The issue here is that you will still be computing all of that data on the browser. If possible it would be better to offload that processing onto the server and use a POST
request for the computing. The promise structure will still look the same.
There is also the issue of whether or not you need these calculatedRatios for the rest of your script. If you don't great, if you do then you would just encapsulate the rest of the script inside of the Promise.all(arrayOfPromises).then(function (result) { //rest of script}
. The key piece of that code being the .then(function () {}).
I would suggest using WebWorkers but alas they are not supported by IE8. There are workarounds found in google code and also here but I can't vouch for how well those options will work.
EDIT: this will show how to make the 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 promisify it using 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 promisify it would look like this:
var Promise = require('q'), //however you want to do this in the browser
calculateRatiosAsync = Promise.promisify(calculateRatios);
I personally like that way because it is compatible with other control flow libraries without having to change the original function, or you can just use the original function the way you have it if it's not necessary to promisify it.
2) The other 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 the promise library differently, but I leave that up to you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With