You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:23:12