Firefox中dispatch Redux异步函数后刷新页面未执行,其他浏览器正常
使用Redux Toolkit + Redux Thunk时,调用dispatch触发异步重置接口后立刻刷新页面,在Chrome、Brave、Edge中正常工作,但Firefox仅刷新页面,完全不执行resetPortfolio异步函数:
const resetPortfolioFunc = (e) => { dispatch(resetPortfolio()); window.location.reload(false); };
尝试过window.location = window.location,问题依旧。
附异步Thunk和Slice代码:
export const resetPortfolio = createAsyncThunk( "/portfolio/resetPortfolio", async (value, thunkAPI) => { const token = thunkAPI.getState().auth.user.token; const userID = thunkAPI.getState().auth.user._id; const newObj = { token, userID }; const url = `http://localhost:3001/api/portfolio/resetPortfolio`; const response = await axios.post(url, newObj); return response.data; } ); export const portfolioSlice = createSlice({ name: "portfolio", initialState, reducers: { reset: (state) => initialState, }, extraReducers(builder) { builder .addCase(resetPortfolio.pending, (state) => { state.resetStatus = "loading"; }) .addCase(resetPortfolio.fulfilled, (state) => { state.resetStatus = "success"; }) .addCase(resetPortfolio.rejected, (state) => { state.resetStatus = "failed"; }); }, });
目前通过监听resetStatus状态在成功后刷新的方案可以工作,但比原代码响应慢,希望找到让原逻辑在Firefox生效的方法,或理解浏览器行为差异的原因。
Firefox与其他浏览器的核心差异在于页面卸载时对未完成异步任务的处理逻辑:
- Chrome、Brave等浏览器在触发页面刷新(
window.location.reload)时,会尝试保留并完成已发起的网络请求后再卸载页面; - Firefox则会立即终止页面内所有未完成的JS任务和未发出/处理中的网络请求。
原代码中,dispatch(resetPortfolio())是异步操作(内部包含axios请求),而window.location.reload(false)是同步执行的页面卸载指令——Firefox在执行reload时,resetPortfolio里的axios请求还没来得及发送就被页面中断,因此看不到任何接口调用和状态变化。
不需要依赖状态监听,直接等待dispatch返回的Promise完成后再刷新页面即可。因为createAsyncThunk的dispatch会返回一个Promise,我们可以用async/await等待请求完成:
const resetPortfolioFunc = async (e) => { try { // 等待异步Thunk执行完成(unwrap()会抛出rejected状态的错误) await dispatch(resetPortfolio()).unwrap(); // 请求成功后再刷新页面 window.location.reload(false); } catch (error) { // 处理重置失败的情况,比如提示用户 console.error("重置失败:", error); } };
这个方案既保证了接口请求一定执行完成,又避免了useEffect监听状态带来的延迟,响应速度和原代码在其他浏览器的表现一致,同时兼容Firefox。
原代码的逻辑本身存在不可靠性:依赖浏览器在页面卸载前完成异步请求是浏览器实现细节,不属于标准行为,不同浏览器或同一浏览器的不同版本都可能有差异。等待异步操作完成后再执行页面刷新,才是符合规范的可靠写法。
内容的提问来源于stack exchange,提问作者Caleb

