【问题标题】:Redux thunk: how to await completion of an async actionRedux thunk:如何等待异步操作的完成
【发布时间】:2016-10-24 14:57:42
【问题描述】:

由于 redux thunk 异步调用动作创建者返回的函数,我如何在调用动作创建者之后确保 redux 在继续之前实际调度了动作?

我需要在每次向服务器发出 POST 请求之前获取 CSRF 令牌,并且对于这两个过程都有相应的操作。

问题是,如果我连续调用这些动作创建者,POST 动作会由于某种原因在 CSRF 动作被调度之前被调度。我想将这些问题分开,所以我不想合并这些操作。

如何将动作创建者调用代码与调度这些动作的 redux thunk 同步?

【问题讨论】:

    标签: javascript html reactjs redux redux-thunk


    【解决方案1】:

    您可以将 thunk action creator 作为 Promise,更容易控制异步作业。

    export function createXHRAction(xhrType, dispatch, options) {
        // you can customize createXHRAction here with options parameter.
    
        dispatch({ type: xhrType, data: { fetching: true, data: [] });
    
        return new Promise( (resolve, reject) => {
            fetch(options.url, { ... })
            .then( (response) => {
                // to getting server response, you must use .json() method and this is promise object
                let parseJSONPromise = response.json();
    
                if(response.status >= 200 && response.status < 300) {
                    parseJSONPromise.then( (result) => {
                        dispatch({ type: xhrType, data: { fetching: false, data: result.data });
                        resolve(result.data);
                    });
                    return parseJSONPromise;    // make possible to use then where calling this
                }
                else {
                    return parseJSONPromise.then( res => {
                        reject({ message: res.error.message });
                    });
                }
            })
            .catch( (error) => {
                // handles common XHR error here
            });
        });
    }
    

    现在您可以像这样轻松创建新的 XHR 操作:

    import { createXHRAction } from './actions';
    
    export function getUser(id) {
        return (dispatch) => {
            return createXHRAction('user', dispatch, {
                method: 'get',
                url: `/user/${id}`
            });
        };
    }
    

    现在您可以使用同步等 thunk 操作:

    import { dispatch } from './store';
    import { getUser } from './action/user';
    
    class SomeComponent extends React.Component {
        ...
        loadData(id) {
    
            // from here, store's state should be { fetching: true, data: [] }
            dispatch(getUser(id))
            .then( (userData) => {
                // now from here, you can get the value from parameter or you can get it from store or component props if super component passing it by redux provider.
                // store state should be { fetching: false: data [..., ...] }
                // do something with received data
            })
            .catch( (error) => {
            }));
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      在开始 POST 请求之前,您需要等待 CSRF-token 请求完成。

      我认为将所有代码封装到动作创建器中会更好

      function postAction(data) {
         fetchToken().then((token) => {
             //you have got token here and can use it for the POST-request.
             doPost(data, token).then(() => {
                //dispatch success action if you need so
             })
         })
      }
      

      【讨论】:

      • 虽然这是一种建设性的解决方法,但在某些情况下,按照发帖人的要求按顺序调度操作会非常有帮助。例如。你正在处理一个复杂的项目,在现有的动作创建器中使用受信任的遗留代码“正常工作”,最好在不修改或重构的情况下调用它们。
      猜你喜欢
      • 1970-01-01
      • 2017-06-15
      • 1970-01-01
      • 1970-01-01
      • 2019-03-20
      • 1970-01-01
      • 2019-04-18
      • 2017-02-15
      • 2023-03-23
      相关资源
      最近更新 更多