Recently, I encountered a scenario where multiple API requests were being made from a common function triggered by various initiators. To address this, I discovered the concept of request coalescing.
Request coalescing is a technique for tracking ongoing API requests and sharing the result among all simultaneous requests.
Why is it important in frontend development?
In applications that rely on authentication tokens, it's common for multiple parts of the app to trigger requests around the same time. If the token has expired, these requests might all attempt a token refresh simultaneously.
Request coalescing ensures that only one refresh request is actually made. All subsequent requests receive the result of that shared ongoing promise, avoiding redundant network calls and improving performance.
Check out the code snippet below :-
let refreshTokenPromise = null;
// function to get auth token
const getAuthorizationToken = async () => {
let token = Cookies.get("token") && JSON.parse(Cookies.get("token"));
// if token is expired
if (token && isTokenExpired(token)) {
if (!refreshTokenPromise) {
// Initiate a new refresh token request
refreshTokenPromise = fetchRefreshToken()
.then((result) => {
const authToken = result?.authorizationToken;
const refreshToken = result?.refreshToken;
if (authToken) {
Cookies.set("token", authToken);
}
if (refreshToken) {
refreshTokenManager().set(refreshToken);
}
return authToken || token;
})
.catch((e) => {
console.error("Error fetching refresh token", e);
return token;
})
.finally(() => {
// Reset the pending request tracker regardless of success or failure
refreshTokenPromise = null;
});
}
// Return the promise of the ongoing refresh request
return refreshTokenPromise;
} else {
return token;
}
};
const isTokenExpired = (token) => {
let currentTime = new Date().getTime();
if (token.expiryTime < currentTime) return true;
};
const fetchRefreshToken = async () => {
// api call to fetch refresh token and return the response
};
So, if you look at the code above, you’ll notice that we’re caching the ongoing promise of the API request. This means that if the function is triggered multiple times simultaneously, it won’t initiate multiple requests—instead, it will return the same in-progress promise to all callers.
Checkout the flow diagram for more clear understanding :-
This effectively ensures that only one API call is made, and the result is shared across all request initiators. Once the promise resolves, all the awaiting calls receive the same response, reducing redundant network requests and improving overall efficiency.
Let me know what you think in the comments !
Top comments (0)