如何使用 redux-thunk 和 try-catch 处理多个调度结果?

Posted

技术标签:

【中文标题】如何使用 redux-thunk 和 try-catch 处理多个调度结果?【英文标题】:How to handle multiple dispatch results from react using redux-thunk and try-catch? 【发布时间】:2020-09-16 11:26:03 【问题描述】:

我正在使用 redux-thunk 进行操作调用,并使用 reducer 返回状态。我的操作本质上是对后端的 axios API 请求。对于一个特定的操作,我需要按照代码中显示的确切顺序调度一组事件:

    检查用户传递的tokenvalue是否有效(对tokencollection有自己的axios api请求)。如果 1. 失败,跳转到 catch 块。 如果token确实有效,使用axios post注册用户。如果2.失败,跳转到catch块 如果用户注册成功,将令牌设置给用户(因此每个用户只有一个唯一令牌)。如果3.失败,跳转到catch块。

为了按上述顺序依次实现它们,我将它们放在 try-catch 块中。原来我对dispatch 工作原理的理解是错误的——如果调度因错误而失败,它仍会执行后续调度。关于如何解决这个问题的任何建议? :

export const register = (name,email,password,tokenval) => async(dispatch) =>
try
    await dispatch(checkTokenValidity(tokenval)); // if this fails, jump to catch block
    const res = await axios.post("/api/users", body, config); //if this fails jump to catch
    await dispatch(setUserToToken( tokenval, userID: res.data.userID )); //if this fails jump to catch
    dispatch(
      type: REGISTER_SUCCESS,
      payload: res.data,
    );
catch(err)
  dispatch(
      type: REGISTER_FAIL,
    );

;

【问题讨论】:

【参考方案1】: 确保 checkTokenValidity 在失败时抛出错误。有了这个,它会自动去 catch 块 无需使用调度和等待令牌有效性 将 api 结果存储在变量中并进行必要的检查并相应地调度操作。

您的重构代码

export const register = ( name, email, password, tokenval ) => async (
  dispatch
) => 
  try 
    const isValidToken = await checkTokenValidity(tokenval); // no need of dispatch - just make sure that the checkTokenValidity throws an error upon fail
    if(!isValidToken )
        throw new Error('server error - invalid token')
    
    const usersResult = await axios.post("/api/users", body, config); //if this fails jump to catch
    if(!usersResult )
        throw new Error('server error - usersResult')
    
    const setUserToTokenResults = await dispatch(setUserToToken( tokenval, userID: res.data.userID )); //if this fails jump to catch
    if(!setUserToTokenResults )
        throw new Error('server error - setUserToTokenResults')
    
    dispatch(
      type: REGISTER_SUCCESS,
      payload: res.data,
    );
   catch (err) 
    dispatch(
      type: REGISTER_FAIL,
      payload: err //<---- provide some error message to the reducer
    );
  
;

【讨论】:

非常感谢您的回复。有没有办法也抛出一个错误,但是我们可以传递一个我们选择的数组而不是传递一个 Error() 类型的对象吗?

以上是关于如何使用 redux-thunk 和 try-catch 处理多个调度结果?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 redux-thunk `bindActionCreators`

如何使用 redux-thunk 和 try-catch 处理多个调度结果?

如何使用 redux-thunk 调度操作让 connected-react-router 重定向?

如何测试 redux-thunk 中间件异步功能?

如何在 Typescript 中使用 redux-thunk 使用 ThunkAction 正确键入 thunk?

使用 axios 和 redux-thunk 以 redux-form 发布请求