React-Redux Thunk中async-await使用问题求助
解决React-Redux中顺序调用API的Async-Await问题
看起来你已经找对了用async-await处理顺序API调用的方向,但在调用第二个action时犯了个小错误,让我帮你一步步修正过来。
问题核心
在getUserJobInfo里,你写了这样一行错误代码:
let newApiResponse = await get(dispatch(fetchUserResumes(pageNo, jobId)));
这里的问题在于:fetchUserResumes是Redux Thunk的action creator,dispatch(fetchUserResumes(...))会直接执行它内部的异步逻辑,并且返回的是该逻辑里的Promise——你不需要再用get()去包裹它,get()是你发起HTTP请求的工具,而fetchUserResumes内部已经用它发起请求了。
修正步骤
1. 优化fetchUserResumes,确保返回可等待的Promise
你的fetchUserResumes已经返回了API请求的Promise,但可以调整错误处理逻辑,让外层能更方便地捕获异常:
export function fetchUserResumes(pageNo, jdId) { pageNo = 0; const size = 20; // 用const更符合变量语义 return (dispatch) => { const pageParam = `page=${pageNo}`; const url = `${FETCH_RESUMES}/${jdId}?${pageParam}&size=${size}`; // 模板字符串更清晰 dispatch({ type: REQUEST_INITIATED }); return get(url) .then((response) => { if (response.status === 200) { dispatch({ type: FETCHING_RESUME_SUCCESS, data: response.payload }); dispatch({ type: REQUEST_SUCCESSED }); return response.payload; // 可选:返回数据给外层使用 } else { // 处理各类非200状态 if (!response.status) { toastr.error('Our server is down. Please check again'); } else if (response.status.status === 401) { dispatch(logout()); } else if (response.status.status === 500) { toastr.error("Error while fetching resumes, please try again"); dispatch({ type: FETCHING_RESUME_FAILED, data: response.status }); } dispatch({ type: REQUEST_SUCCESSED }); // 抛出错误让外层catch捕获(可选) return Promise.reject(new Error('Fetch resumes failed')); } }) .catch((error) => { // 捕获网络层面的错误 toastr.error('Network error while fetching resumes'); dispatch({ type: REQUEST_SUCCESSED }); return Promise.reject(error); }); }; }
2. 修正getUserJobInfo的顺序调用逻辑
现在你可以直接await dispatch(fetchUserResumes(...)),因为dispatch Thunk action会返回内部的Promise:
export function getUserJobInfo(jobId) { return async (dispatch) => { dispatch({ type: REQUEST_INITIATED }); const url = `${GET_JOB_INFO_URL}${jobId}`; // 模板字符串优化拼接 try { const response = await get(url); if (response.status === 200) { dispatch({ type: USER_JOB_INFO, data: response.payload }); // 第一个API成功后,等待第二个API完成 await dispatch(fetchUserResumes(0, jobId)); } else { // 处理第一个API的非200情况 dispatch({ type: REQUEST_SUCCESSED }); if (response.status?.status === 401) { dispatch(logout()); } else { toastr.error('Failed to fetch job info'); } } } catch (error) { // 捕获第一个API的网络错误或自定义抛出的错误 toastr.error('Network error while fetching job info'); dispatch({ type: REQUEST_SUCCESSED }); } }; }
3. 在组件中调用action
在你的组件的componentDidMount里,直接dispatch这个action即可:
componentDidMount() { const { jobId } = this.props; // 假设jobId从props获取 this.props.dispatch(getUserJobInfo(jobId)); }
如果用了connect高阶组件,也可以把getUserJobInfo映射到props,直接调用this.props.getUserJobInfo(jobId)。
关键知识点
- Redux Thunk允许action creator返回函数,
dispatch(thunkAction)会返回该函数的返回值(也就是内部的Promise),因此可以用await等待异步逻辑完成。 - 用
try-catch包裹async-await代码,能更优雅地处理网络错误或自定义抛出的异常,避免未捕获的Promise报错。 - 模板字符串可以让URL拼接更清晰易读,减少拼写错误。
内容的提问来源于stack exchange,提问作者ganesh kaspate
相关产品推荐
相关产品推荐

