Redux thunk:如何等待异步操作的完成
Posted
技术标签:
【中文标题】Redux thunk:如何等待异步操作的完成【英文标题】:Redux thunk: how to await completion of an async action 【发布时间】:2016-10-24 14:57:42 【问题描述】:由于 redux thunk 异步调用动作创建者返回的函数,我如何在调用动作创建者之后确保 redux 在继续之前实际调度了动作?
我需要在每次向服务器发出 POST 请求之前获取 CSRF 令牌,并且对于这两个过程都有相应的操作。
问题是,如果我连续调用这些动作创建者,POST 动作会由于某种原因在 CSRF 动作被调度之前被调度。我想将这些问题分开,所以我不想合并这些操作。
如何将动作创建者调用代码与调度这些动作的 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
)
)
【讨论】:
虽然这是一种建设性的解决方法,但在某些情况下,按照发帖人的要求按顺序调度操作会非常有帮助。例如。你正在处理一个复杂的项目,在现有的动作创建器中使用受信任的遗留代码“正常工作”,最好在不修改或重构的情况下调用它们。以上是关于Redux thunk:如何等待异步操作的完成的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Redux 异步 thunk 中使用 AppDispatch 类型?