Make Your JavaScript More Asynchronous
Have you been wondering how you can make your JavaScript more asynchronous? Have you been wondering how to handle computationally expensive tasks without blocking the main execution thread? Look no further!
Time and time again, I’ve seen JavaScript developers create a for loop that goes on and on, or worse yet, a ‘while true’ loop. Surely if you’ve ever implemented such features within your application, you’ve seen how the application itself can suffer when things get out of hand. This logic applies to all forms of JavaScript developers, from front end developers through to back end developers and all in-between.
One simple technique that can be used is JavaScript’s very own set timeout feature, you could use set interval, however due to the fact that using set interval would create a unique timer every time the function is called, whereas set time out makes a unique timer every time the function ends. In theory implying that the set interval approach is more likely to be inefficient, also implying that the set timeout approach would be slower. At the end of the day, as long as your application never consumes up too much of the devices resources for one feature, it shouldn’t be a problem.
(If you’d like to look more into the KISS principal take a look at this link.)
Let’s say that you have an array, an array that’s an unrealistic size, let’s say 10 million, likelihood is that your data structure(s) wouldn’t get that big, but again, for the sake of argument, let’s just say that for whatever reason, you need to iterate over 10 million objects in an array. If you tried to simply iterate over such a data-structure, the odds are that you’d want to carry out some form of computation/operation(s) on ‘z’ data, there could be some device(s) that would suffer.
This point targets front end/hybrid app developers specifically as they’re building their web based application(s) to work on a wide array of devices, therefore you should want the best user experience possible. Mobile devices have much less resources compared to a lot of desktop devices, and depending on the level of support you wish to implement, you may even wish to support devices such as a Raspberry Pi which has even less resources than a lot of modern day mobile phones.
Anyway, I believe it’s time for a demonstration! Within this demonstration I’ll be implementing asynchronous style code via the use to the callback approach.
/**
* This encapsulates all of the 'complexity' behind handling
* computationally expensive features, an example being iterating over
* a rather large data-set.
*/
const AsyncDemo = (callback) => {
console.time('Test');
const limit = 10000000; // 10,000,000
const cooldown = 120;
const loop = 10000;
let iteration = 0;
let arr = [];
let timeout = null;
let onCooldown ?= () => { console.log('Pause..'); };
/**
* This function will simply state whether or not the current
* load timeout should be cleared or not.
*/
const isComplete = () => {
if (arr.length >= limit)
{
// Use of try catch just for the sake of preventing error(s).
try { clearTimeout(timeout); }
catch (e) { cosnole.log(e); }
// Print the array and end the console time with the key 'Test'.
// console.log(arr); - This alone takes a while...
console.timeEnd('Test');
return true;
}
return false;
};
/**
* This method is simply here to add some object to an array,
* that's about it.
*/
const addToArray = (i) => {
const obj =
{
id: i,
job: 'consume',
detail: 'memory',
age: new Date().getTime()
};
arr.push(obj);
};
/**
* This is essentially the main block of the code, this
* is where the 'magic' happens.
*/
const process = () => {
console.log('Running Process!' + (iteration++));
for (let i = 0; i < loop; i++)
{
// If is complete, make an early return.
if (isComplete())
{
if (typeof callback === 'function') return callback(arr);
else return alert('Complete!');
}
// No need for an else statement.
addToArray(i);
}
onCooldown();
timeout = setTimeout(process, cooldown);
};
// Start the process.
process();
};
// Start the demo.
const demo = AsyncDemo();
As you can see in the example above, the code will iterate over the stated number of elements, however it will take 120 ms interval ‘pauses’ between each ‘iteration’, of course this can be programmed in such a way that it can take more or less time, etc. You can see that with this implementation, it’s essentially an outline of how you could create your own asynchronous method class/object/etc. You even have room for an on cool down method, this method alone will run when the script is waiting to start the next timeout.
Yes, the time(s) aren’t the best in this example, but that’s a part of the point of asynchronous style coding, it’s not designed to be the fastest solution out there, it’s used to get the best of performance – usability ratio. The true meaning of asynchronous coding is to have some code run ‘in the background’, while the main bulk of the application processes other information. To expand upon the above example, most asynchronous solutions also include some form of error handling method, I’ve not included such a feature in the above solution again for the sake of simplicity.
Finally, I’d like to add that while asynchronous coding is an amazing implementation for a lot of features, it’s not always the best approach, sometimes it’s a much better idea to write synchronous style code. An example being iterating over a very small data structure, using an asynchronous approach would just be wasting time, there would be no added advantage, therefore a synchronous approach would be more suitable. Also do not mistake concurrent programming for asynchronous programming, concurrent programming is having two tasks run in parallel, asynchronous programming is having one task wait for some other task to finish, which simulates parallel computing on a single threaded system, but it is not the same as parallel computation.
(Learn more about when to use and when not to use asynchronous programming here)
Made with ? by Me - Joseph Evans