JavaScript: Concurrency Handling
Sometimes, we need to call multiple independent api call in our page, something like this :
After checking the network request, we can see that the requests are running sequentially. Can we improve the code, so each request will not waiting each other?
1. Await separately
The first approach is simple enough, we fire all request without await, and then await each request and handle the error.
The api call will be faster. But there are some trade-offs in this approach :
- No Fail-Fast
Unfortunately, the simultaneous process will only happened in a best case scenario, if userPromise / productPromise is error, the next request will be halted until the userPromise / productPromise complete. - Error Handling
It is not possible to correctly handle errors of async parallel tasks triggered with multiple awaits. If error happened, you will get UnhandledPromiseRejectionWarning, and PromiseRejectionHandledWarning, regardless of where you use try/ catch
Let's go to the next one:
2. Promise.all
We can do workaround by catch statement to each promise we pass into the Promise.all. If any of the promises reject, they’ll be resolved through the catch statement chained to the specific promise.
However it's also have a trade-off : we need to make sure we are always providing that .catch(onReject) religiously, throughout our code. Which easy to miss.
Is there any better approach? Sure.
3. Promise.allSettled
The code above can be improved, by create a generic function to return the response or throw any error.
Nicer on the eyes right? While Promise.all act all-or-nothing, Promise.allSettled will always return an array of objects, each of these objects further contains two properties: status and value.
So, which solution will you prefer? or can i say, which trade-off will you choose?
There are no perfect solutions, there are only trade-offs; and you try to get the best trade-off you can get, that's all you can hope for. - Thomas Sowell
Comments