如何正确使用createAsyncThunk?异步Thunk代码导致应用崩溃求助
问题根源
你遇到的崩溃是async函数返回特性、fetch错误处理机制和后续状态处理逻辑共同导致的:
async函数默认会把返回值包装为Promise,你在async函数内部又主动返回了fetch().then()产生的Promise,相当于返回了嵌套的Promise结构,再叠加fetch不会对4xx/5xx这类HTTP错误状态自动抛出异常的特性,当接口返回非2xx状态时,res.json()可能抛出解析错误,你没有对这个错误做捕获,未捕获的异常向上传递就会导致应用崩溃。- 移除
async之后,createAsyncThunk会直接接收fetch返回的Promise,其内部自带的异常捕获逻辑会正常接住请求过程中产生的错误,所以不会触发全局崩溃。
createAsyncThunk正确用法
推荐写法:async/await搭配错误捕获
export const getBarbers = createAsyncThunk( "/barbers/fetchBarbers", async (_, { rejectWithValue }) => { try { const res = await fetch("/api/barbers"); // 手动校验HTTP状态码,弥补fetch的默认缺陷 if (!res.ok) { throw new Error(`请求失败,状态码:${res.status}`); } return await res.json(); } catch (err) { // 将错误传递给rejected case做业务处理,避免未捕获异常 return rejectWithValue(err.message); } } );
可选写法:纯Promise链式调用
export const getBarbers = createAsyncThunk( "/barbers/fetchBarbers", (_, { rejectWithValue }) => { return fetch("/api/barbers") .then(res => { if (!res.ok) throw new Error(`请求失败,状态码:${res.status}`) return res.json() }) .catch(err => rejectWithValue(err.message)) } );
配套状态处理要求
需要在createSlice的extraReducers中完整处理请求的三个状态,避免后续取值报错:
const barbersSlice = createSlice({ name: "barbers", initialState: { list: [], loading: false, error: null }, extraReducers: builder => { builder .addCase(getBarbers.pending, (state) => { state.loading = true state.error = null }) .addCase(getBarbers.fulfilled, (state, action) => { state.loading = false state.list = action.payload }) .addCase(getBarbers.rejected, (state, action) => { state.loading = false state.error = action.payload || "请求理发师列表失败" }) } })
内容的提问来源于stack exchange,提问作者Jevon Cochran
相关产品推荐
相关产品推荐

