redux - 一种使用 createAsyncThunk 触发多个异步操作的简洁方法
问题描述
我们正在延迟 React-Redux Web 应用程序的渲染,直到 Redux 商店中的几个异步应用程序初始化任务完成。
这是设置存储然后触发初始化操作的代码:
export const setupStoreAsync = () => {
return new Promise((resolve, reject) => {
const store = setupStore()
store
.dispatch(fetchAppInitialization())
.then(unwrapResult)
.then(_ => resolve(store))
.catch(e => reject(e.message))
})
}
承诺拒绝非常重要,因为它用于在应用程序无法正确设置的情况下为用户呈现错误消息。这段代码非常好读并且运行良好。
问题在于动作创建者:
export const fetchAppInitialization = createAsyncThunk(
'app/initialization',
(_, thunkApi) =>
new Promise((resolve, reject) =>
Promise.all([thunkApi.dispatch(fetchVersionInfo())]).then(results => {
results.map(result => result.action.error && reject(result.error))
})
)
)
这段代码工作得很好。如果这些操作中的任何一个失败,则 Promise 将被拒绝,并且用户会看到一条错误消息。但它很丑 - 它不像我们正常的动作创作者那么漂亮:
export const fetchVersionInfo = createAction('system/versionInfo', _ => ({
payload: {
request: { url: `/system/versionInfo` },
},
}))
我们会在某个时候触发多个 fetch 请求fetchAppInitialization
,所以这个Promise.all
函数肯定是必需的。我们希望能够使用 Redux-Toolkit 的createAction
语法来触发多个承诺的动作,以缩短这个动作创建者,但我不知道这是否可能。
注意:我redux-requests
用来处理我的 axios 请求。
甚至是createAsyncThunk
必需的吗?
解决方案
因为fetchAppInitialization
除了这个单一的用例我没有使用任何动作,我只是简单地删除它并将逻辑直接移动到setupStoreAsync
函数中。这有点紧凑。这不是最优的,因为results.map
仍然包含逻辑,但至少我们不再使用createAsyncThunk
。
export const setupStoreAsync = () => {
return new Promise((resolve, reject) => {
const store = setupStore()
new Promise((resolve, reject) =>
Promise.all([store.dispatch(fetchVersionInfo())]).then(results => {
results.map(result => result.action.error && reject(result.error))
resolve()
})
)
.then(_ => resolve(store))
.catch(e => reject(e.message))
})
}
更新:我能够通过使用async/await
.
export const setupStoreAsync = async () => {
const store = setupStore()
const results = await Promise.all([store.dispatch(fetchVersionInfo())])
results.forEach(result => {
if (result.action.error) throw result.error
})
return store
}
推荐阅读
- python - 无法从 Python 3.6 上的 datetime 模块导入时区
- mongodb - 配置 MongoDB 以通过 Linux PAM 验证用户密码
- android - 根据当前位置自动更改货币符号
- c - 我怎样才能重写程序,这样我就不必调用`flex`而只调用`bison`和`cc`?
- c++ - 在 C++ 中混合模板参数和变量时的分支
- aggregate-functions - 如何通过 Tableau 中的聚合按组聚合?
- microservices - Spring 数据流和 GCP Pub Sub
- mysql - 如何在子查询中使用 Count?
- java - 排序图
> 使用 Java 8 - firebase-realtime-database - 为了按距离对地理查询结果进行排序,我必须阅读整个数据集吗?