feat: Add partial sync execution to request interceptors #5759
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What is this about?
This PR makes the execution of request interceptors flagged as synchronous to always be synchronous as long as there isn't any async interceptors added after them.
Why is this relevant?
In Vue, the
watchEffect
function captures reactive dependencies synchronously within a function execution.So, in order to trigger an update on a component within an axios call, all reactive bindings must be used synchronously.
Currently, if we use an axios instance with only sync interceptors, we can trigger updates by using reactive variables inside them, but if we add a single async interceptor (even if it will be executed after the sync ones), we lose this capability. A real world example is a header tracked by a Pinia store added synchronously before an access token is issued asynchronously to be set on the
Authorization
header.Other frameworks might do something similar and sometimes we might need to perform an action synchronously before any request but also have some async tasks to do.
Considered cases
Instance without any request interceptors
Execution will be as usual. The adapter will be called synchronously and then the response interceptors will be called asynchronously one by one.
Instance with only sync request interceptors
Same as above. All interceptors being executed synchronously (and the adapter).
Instance with only async request interceptors
Same as above. All interceptors will be executed asynchronously, but the adapter will still be called synchronously.
Instance with sync interceptors added AFTER async ones
Since interceptors are executed in a LIFO way, we can execute the sync interceptors synchronously, then continue the execution as if all the next interceptors were async.
Instance with sync interceptors added BEFORE async ones
Since interceptors order of execution must be respected, those sync interceptors must be called after the async ones are resolved, which means we cannot call them synchronously, so we proceed to call the interceptor chain as if all interceptors were async.