首页 文章

如何等待redux thunk发送动作

提问于
浏览
5

当redux thunk异步调用动作创建者返回的函数时,我怎样才能确保在调用动作创建器之后redux实际上已经调度动作然后再继续?

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

问题是,如果我连续调用这些动作创建者,POST动作由于某种原因在调度CSRF动作之前被调度 . 我想将这些问题分开,所以我不想将这些行为结合起来 .

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

2 回答

  • 2

    您可以将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) => {
            }));
    
        }
    }
    
  • 6

    在启动POST请求之前,您需要等待CSRF令牌请求完成 .

    我认为将所有代码包装成动作创建者会更好

    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
           })
       })
    }
    

相关问题