我的 RTK 查询拦截器有问题,我通过扩展 fetchBaseQuery 实现了自动重新授权 RTK query documentation现在我有一个问题,如果多个请求被触发并且 token 无效,所有请求都将得到 401 作为响应,并且所有请求都将尝试刷新 token ,这将导致第一个成功,其他将失败,然后 else 将触发并返回用户登录屏幕。
有什么办法可以避免这种情况吗?
let result = await baseQuery(args, api, extraOptions)
if (result.error && result.error.status === 401) {
// try to get a new token
const refreshResult = await baseQuery(
{
url: `http://.../${refreshToken}`,
method: 'POST'
},
api,
extraOptions
);
if (refreshResult.data) {
// store the new token
api.dispatch(tokenReceived(refreshResult.data))
// retry the initial query
result = await baseQuery(args, api, extraOptions)
} else {
api.dispatch(loggedOut())
}
}
return result
最佳答案
一个可能的解决方案是使用互斥体。我们在 this github discussion 中讨论了可能的解决方案:
import { Mutex } from 'async-mutex';
const mutex = new Mutex();
const baseQueryWithReauth = async (args, api, extraOptions) => {
await mutex.waitForUnlock();
let result = await baseQuery(args, api, extraOptions);
if (result.error && result.error.status === 401) {
if (!mutex.isLocked()) {
const release = await mutex.acquire();
try {
const refreshResult = await baseQuery(
{
url: 'auth/refresh/',
method: 'POST',
body: { getToken(), getRefreshToken() },
},
api,
extraOptions,
);
if (refreshResult.data) {
api.dispatch(tokenUpdated(refreshResult.data));
// retry the initial query
result = await baseQuery(args, api, extraOptions);
} else {
api.dispatch(logout());
}
} finally {
release();
}
} else {
await mutex.waitForUnlock();
result = await baseQuery(args, api, extraOptions);
}
}
return result;
};
const baseApi = createApi({
baseQuery: baseQueryWithReauth,
endpoints: () => ({}),
});
关于reactjs - RTK查询拦截多个请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70789043/