Most of the times, we have to call API to create, read, update or delete (CRUD) the resource on some server (in layman terms).
I am saying API, but what I am talking about is performing any asynchronous task
in serial or parallel manner.
Before moving forward, you should be aware of Promise and methods like Promise.all() and Promise.allSettled() as they will be used to demonstrate the examples.
You can get the code used in this example from here for you to try it out yourself.
Serial API Calling
Lets make a function for a fake API call:
function fakeAPICall(id, delay) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (typeof id === 'number') {
resolve(`Response from API call ${id}`);
} else {
reject(`Provide id number in API call}`);
}
}, delay);
});
}
For serial calling, we can use this function:
async function serialExecution() {
console.time('serialExecution')
try {
const response1 = await fakeAPICall(1, 1000);
console.log(response1);
const response2 = await fakeAPICall(2, 1500);
console.log(response2);
const response3 = await fakeAPICall(3, 1200);
console.log(response3);
} catch (error) {
console.error(error);
}
console.timeEnd('serialExecution')
}
serialExecution();
When I executed it, I got this response:
Response from API call 1
Response from API call 2
Response from API call 3
serialExecution: 3.739s
As you can see that each API was called one by one and the total execution (on my system) was completed in 3.739 seconds
.
Parallel API Calling
In order to call APIs in parallel manner, you have to use promise.all()
or promise.allSettled()
method as per your use-case.
You should use promise.all()
if you want to make sure to receive the result of all promises whereas, you should use promise.allSettled()
if you want to receive the result of all the APIs whether they return response or error out. For more details of how promise methods work, their differences and use-cases, please read this.
Now... Let's dive into the code:
async function parallelExecution() {
console.time('parallelExecution')
try {
const promises = [
fakeAPICall(1, 1000),
fakeAPICall(2, 1500),
fakeAPICall(3, 1200)
];
const responses = await Promise.all(promises);
// const responses = await Promise.allSettled(promises);
console.log(responses);
} catch (error) {
console.error(error);
}
console.timeEnd('parallelExecution')
}
parallelExecution();
When I executed it, I got this response:
[
'Response from API call 1',
'Response from API call 2',
'Response from API call 3'
]
parallelExecution: 1.514s
As you can see that result was received 1.514 seconds
, all at once.
Please note that, the result from this process is as slow as the slowest response from any of the API.
For example:
- API 1 takes 1 second.
- API 2 takes 2 seconds.
- API 3 takes 3 seconds.
Then the response will be returned after 3 seconds when the slowest API response has returned.
You can try this code for allSettled()
as well.
Is it really parallel?
The answer is no. The requests are sent in concurrent manner, not in parallel manner.
Parallel Execution means that the three API should be executed by three threads in parallel manner.
BUT
We know that JavaScript is single-threaded and with the use of event-loop, it gives us an illusion of parallelism but in reality, it's a concurrent behavior.
However, there are ways to achieve parallel behavior using techniques like Web Workers and child processes in Node.js but we will get down to them in our future blogs =)
Conclusion
In this blog we learned calling APIs or performing asynchronous operations in sequential manner as well as in concurrent (not parallel) manner.
I hope you learned something from this :-)
Follow me for more such content:
LinkedIn: https://www.linkedin.com/in/shameeluddin/
Github: https://github.com/Shameel123