I am wanting to learn how to run functions in parallel/concurrently in JavaScript. Over the past few days I've read several pages about promises, async functions, call backs and await, but I find most of the articles poorly written, unclear or the examples when run do no appear to be running in parallel, but I suspect just that the example used for example setTimout to defer a function call so the functions calls are not carried out in the order they appear in the code.
Here is what I mean when I say I want parallel processing. Lets say I had two functions that did a lot of work, in this example lets use counting, I will use small numbers but imagine if these numbers were very big.
var funcA = function(){
for(var x = 0; x < 5;x++) {console.log("A:" + x};
console.log("A done.");
}
var funcB = function(){
for(var x = 0; x < 10;x++) {
console.log("B:" +x}; console.log("B done.");
}
What I would hope to see if I were able to run these in parallel is somthing such as:
A:1
A:2
B:1
A:3
B:2
B:3
A:4
B:4
A:5
A Done.
B:5
B:6
B:7
B:8
B:9
B Done.
So I have been following an example at medium.com, and as is typical with these countless examples, they never show the processes doing any real work, and I think time outs are used to simulate it. The trouble is, its hard to see what timeouts are causing/assisting in parallel processing and which ones simulate work being done. With the example mentioned, if you make the program do some real work, you will see in fact that it is sequential (many examples I have looked at seem to be this way). The example below is based on the one from the medium.com article, but instead of using a timeout to simulate a long running task I am using a loop to count from 0 to a random number (I've left the timeout in but commented it out and instead replaced it with a for loop and call to the resolve function.This makes each call to makeRequest different in size and therefore the order of completion should change each time.
function makeRequest(letter) {
return new Promise((resolve, reject) => {
var rand = Math.random()* 999;
for(var i = 0; i < rand; i++){
console.log(i + " " + letter);
}
resolve({'status':'done ' + letter});
//setTimeout(() => resolve({ 'status': 'done '+letter }), 2000);
});
}
async function process(arrayOfPromises) {
console.time(`process`);
let responses = await Promise.all(arrayOfPromises);
for(let r of responses) {console.log(r);}
console.timeEnd(`process`);
return;
}
async function handler() {
let arrayOfPromises = [
makeRequest('a'),
makeRequest('b'),
makeRequest('c'),
makeRequest('d'),
makeRequest('e'),
];
await process(arrayOfPromises);
console.log(`processing is complete`);
}
handler();
However, I can see that if I run the code, its not parallel/concurrent but sequential as in.
A:1
A:2
A:3
A:4
B:1
B:2
B:3
C:1
C:2
C:3
D:1
D:2
D:3
D:4
E:1
E:2
{status: 'done a'}
{status: 'done b'}
{status: 'done c'}
{status: 'done e'}
{status: 'done f'}
Questions:
- a) What am I not getting about this?
- b)What needs to be done to the above code so that JavaScript executes the method calls to makeRequest consurrently?
- c) Is what I want even possible in JavaScript (given the single threaded execution of JavaScript and the event loop). It seems to me that really despite all these bloggers calling it parallel and concurrent (I know they are slightly different terms) it is in fact not!.