createAsyncThunk是否创建thunk?二者区别及替代关系说明
Redux中createAsyncThunk与thunk相关问题答疑
1. createAsyncThunk是否会创建thunk?
是。
createAsyncThunk的核心产出就是标准的Redux thunk函数。它接收两个核心入参:一个标识动作类型的字符串前缀,一个返回Promise的异步执行回调,自动生成pending/fulfilled/rejected三个请求状态对应的action type,最终返回的函数完全符合thunk的函数签名——可以接收dispatch、getState作为入参,支持直接传入dispatch触发执行,不需要额外做格式转换。
2. thunk与createAsyncThunk是否是完全不同的两个技术概念?
不是,二者是基础能力与上层封装的从属关系,并非完全独立的两个技术概念:
- thunk 是Redux生态中处理异步逻辑的基础中间件方案,核心能力是允许store接收函数类型的入参而非仅支持普通plain object action,开发者可以在这类函数(也就是手写thunk)中编写任意同步/异步逻辑,灵活度极高,没有固定的代码范式。
- createAsyncThunk 是Redux Toolkit提供的工具函数,专门针对「异步请求+三态状态派发」这个最高频的thunk使用场景做了模板代码封装,它生成的产物本质就是标准thunk函数,完全运行在redux-thunk中间件的能力之上,没有脱离thunk的技术范畴。
举个直观的对比例子,手写一个拉取用户信息的thunk需要写全三态派发逻辑:
// 手写原生thunk const fetchUser = (userId) => async (dispatch, getState) => { dispatch(fetchUserPending()) try { const res = await userApi.getDetail(userId) dispatch(fetchUserFulfilled(res.data)) } catch (err) { dispatch(fetchUserRejected(err.message)) } }
用createAsyncThunk实现时,不需要手动定义三个action creator,也不需要手写try/catch和状态派发的重复代码:
// createAsyncThunk生成的等价thunk const fetchUser = createAsyncThunk('user/fetchUser', async (userId) => { const res = await userApi.getDetail(userId) return res.data })
3. createAsyncThunk是否可以完全替代thunk?
不能。
createAsyncThunk只覆盖了通用异步请求场景的模板代码封装,而原生thunk的能力边界要宽得多,以下常见场景都无法用createAsyncThunk完全覆盖,依然需要手写原生thunk实现:
- 需要结合当前store状态做复杂条件判断的逻辑,比如判断已有缓存是否有效、当前是否正在发同类请求,再决定要不要触发异步请求
- 一个逻辑流中需要穿插多个副作用操作,比如依次派发多个动作、中间穿插路由跳转、本地存储读写、日志上报、弹窗触发等非状态更新操作
- 需要实现定制化异步控制逻辑,比如请求取消、轮询、多异步流程串行/并行编排等复杂逻辑
简单说:createAsyncThunk是帮你少写重复thunk代码的工具,不是用来替代thunk本身的。
内容的提问来源于stack exchange,提问作者BigDaddyTrump
相关产品推荐
相关产品推荐

