是否有可能 return 在 Redux Action 的早期

Is it possible to return early in a Redux Action

问题
我觉得这是一个范围界定问题。我无法在 catch 块中 return。它总是 returning 成功。虽然 if 语句适用于失败部分(我使用 console.log 调试它)。

背景资料
有一个使用 laravel 的后端 API。在这段代码中,我登录到 API 以使用 react-redux 获取 JWT 令牌。将来调用 API 需要此令牌。该代码运行良好,并在 实际成功 时收到令牌,但我无法 return 尽早失败。

export function requestApiToken(username, password){    
    const url = ROOT_URL + 'user/login';
    const request = axios.post(url, {
        email: username,
        password: password,
        headers: {
            'Content-Type': 'application/json',
            'X-Requested-With': 'XMLHttpRequest'
        }
    })
    .catch(function (error) {
        //somehow it always returns an error
        //currently 500=succes (will fix that later in api to 200)

        if(error.response.status == 500){
            console.log('succes')
            console.log(error.response.data);
        }else{
            console.log('error')
            console.log(error.response.data);
            return{
                type: FETCH_API_TOKEN_FAILURE,
                token: null,
                message: 'Please enter a valid e-mail and username for the API and try again'
            }
        }
    });

    return{
        type: FETCH_API_TOKEN_SUCCES,
        token: request, //should be error.response.data
        message: 'Succesfull login'
    }
}

编辑作为对评论部分的回复。
这是服务器 returns:

如果块成功(调试)

如果块失败(调试)

目前代码总是进入代码块returnFETCH_API_TOKEN_SUCCES

正如答案中所建议的,我通过使用 redux-thunk 作为我的中间件而不是 redux-promise

来实现它

已添加到 index.js

import thunk from 'redux-thunk';
const createStoreWithmiddleware = applyMiddleware(thunk)(createStore);

在requestApiToken方法中

return(dispatch) => {
        request.then(function (response) {
            dispatch({
                type: FETCH_API_TOKEN_SUCCESS,
                token: response.data.token,
                message: 'Successfull login'
            })
        });
        request.catch(function (error) {
            if(error.response.status == 422){
                dispatch({
                        type: FETCH_API_TOKEN_FAILURE,
                        token: null,
                        message: 'Please enter a valid e-mail and username for the DiabetesAPI and try again'
                })
            }
        });

        dispatch({
            type: FETCH_API_TOKEN_PENDING,
            token: null,
            message: 'Pending API Token request'
        });
    }

万一失败,您的申请流程如下所示:

  1. return FETCH_API_TOKEN_SUCCESSpost 承诺得到解决之前
  2. 网络调用失败,承诺是rejected并且catch块被执行
  3. JS 引擎处理 catch 块语句和 return 具有 FETCH_API_TOKEN_FAILURE 操作类型的新承诺

我建议您使用三态方法进行网络调用,例如PENDING, SUCCESS and FAILURE。在这种情况下,您可以显示加载器并准确知道您的网络调用何时结束。

export function requestApiToken(username, password) {
    const url = ROOT_URL + 'user/login';
    const request = axios.post(url, {
        email: username,
        password: password,
        headers: {
            'Content-Type': 'application/json',
            'X-Requested-With': 'XMLHttpRequest'
        }
    })
    .then(function (response) {
        return {
            type: FETCH_API_TOKEN_SUCCESS,
            token: response.token,
            message: 'Successfull login'
        }
    })
    .catch(function (error) {
        return {
            type: FETCH_API_TOKEN_FAILURE,
            token: null,
            message: getErrorMessage(error.response.status)
        }
    });

    return Promise.resolve({
        type: FETCH_API_TOKEN_PENDING,
        token: null,
        message: 'Loading'
    });
}

function getErrorMessage(statusCode) {
    if (statusCode == 422) { 
        return 'Please enter a valid e-mail and username for the API and try again';
    } else {
        return 'Error has occurred';
    }
}

请注意,您需要在减速器中通过 then 解析 action creator 的值,因为 return 值将是 Promise

正如其他人注意到的那样,您将需要 redux-thunk 中间件来处理 reducer 中的承诺。

P.S。您正在使用 token: request 字段 returning FETCH_API_TOKEN_SUCCESS 操作。在这种情况下,request 是一个承诺,我假设您在进一步的代码中正确处理了它。

P.S.S 很可能你的 catch 块没有 return 任何东西,因为 catch 中的 return 语句将被包装到 promise 中,你需要解决它通过 thencatch

呃,你的代码有很多问题。慢慢来并了解您尝试使用的每个概念如何工作可能是个好主意。

动作创建器是一个函数,return是一个描述动作的普通对象。

A​​xios 是一个库,可让您向服务器发出请求。 Axios.post() 将 return 一个承诺,它允许您使用 then() 和 catch() 方法处理请求的结果。这些方法采用回调函数,并且您已经正确地为您的 catch() 调用提供了一个回调函数。问题是回调 return 中的 return 语句来自回调,而不是来自动作创建者。您不能在动作创建者中进行异步 API 调用,然后 return 来自成功或失败回调的动作。

另一个问题是您 return 在 Axios.post() 调用后立即执行成功操作。这意味着操作创建者将在发出调用后立即 return 成功操作,而无需等待它 return 响应。

如果您想在动作创建者中进行 API 调用,请查看 redux-thunk 这是 Redux 中间件,它可以让您 return 来自动作创建者的承诺反过来又可以在解决或拒绝时调度他们自己的操作。