Thunk 引入背景

这是一个关于Redux异步数据流的故事。引入thunk中间件的完整故事在Redux官方中文文档异步数据流
<http://www.redux.org.cn/docs/advanced/AsyncFlow.html>。一句话总结就是:原生Redux只支持同步数据流,
所以需要引入中间件(middleware) Thnuk 来支持异步数据流。这里有两个关键字:中间件和异步。

Thunk 是什么

A thunk is a function that wraps an expression to delay its evaluation.
// calculation of 1 + 2 is immediate // x === 3 let x = 1 + 2; // calculation
of 1 + 2 is delayed // foo can be called later to perform the calculation // foo
is a thunk! let foo = () => 1 + 2;
用Thunk传递的Action有什么特征

* An action creator that returns a function to perform asynchronous dispatch.
* An action creator that returns a function to perform conditional dispatch.
function incrementIfOdd() { return (dispatch, getState) => { const { counter }
= getState();if (counter % 2 === 0) { return; } dispatch(increment()); }; }
Thunk 怎么用
import { createStore, applyMiddleware } from 'redux'; import thunk from
'redux-thunk'; const storeWithMiddleware = createStore( rootReducer,
applyMiddleware(thunk) );function makeASandwichWithSecretSauce(forPerson) {
return function (dispatch) { return fetchSecretSauce().then( ........ ); }; }
// Thunk middleware lets me dispatch thunk async actions // as if they were
actions! storeWithMiddleware.dispatch( makeASandwichWithSecretSauce('Me') );
以上只是一个简单的总结,具体可以参考github上Thunk 官方文档 <https://github.com/gaearon/redux-thunk>

接下来步入正题:

Redux Thunk 源码
<https://github.com/gaearon/redux-thunk/blob/master/src/index.js>
function createThunkMiddleware(extraArgument) { return ({ dispatch, getState })
=> next => action => { if (typeof action === 'function') { return
action(dispatch, getState, extraArgument); }return next(action); }; } const
thunk = createThunkMiddleware(); thunk.withExtraArgument =
createThunkMiddleware;export default thunk;
我没有漏掉,就是这么短!撇开Redux,单从代码上来看似乎很简单,thunk就是一个嵌套函数。但又感觉啥也没看,还是不知道thunk是干啥的。。。。

我们先假设extraArgument为空,这样可以把问题简单化。

我在看这段源码时想了一下为啥感觉看了像没看一样,总结出了三个待回答的问题:

1. dispatch, getState 哪儿来的?
2. next干啥的?
3.为啥会有这种操作:action(dispatch, getState, extraArgument);


注:action作为一个用户自己根据业务逻辑自己编写的异步函数也不可能用redux中的dispatch和getState作参数呀。

dispatch, getState 哪儿来的?
next干啥的?

我在文章的开头用红色标注过,thunk的本质是中间件(middleware),所以要了解它必须放在Redux
applyMiddleware这个大前提下,这样就迎刃而解了。

之前我写过一篇文章:理解Redux底层原理从applyMiddleware开始
<http://blog.csdn.net/Napoleonxxx/article/details/79321062>

首先,thunk是中间件,它的定义符合中间件函数的格式:
// 中间件大致定义格式 middlwware = store => next => action => { ..... let result =
next(action) .....return result; }
下图是applyMiddleware的部分源码:



从图中我认为可以回答前两个问题,我就不多说了。

action(dispatch, getState, extraArgument)

首先,涉及到应用到thunk的action creator的合法写法:
let thunkActionCreator = () => (param1, param2) => { .... param1({actionType:
value}); ..... }//注意:此时的dispatch其实已经包裹了引入的middleware的逻辑 //dispatch=
fn1Middle(fn2Middle(store.dispatch)) storeWithMiddleware.dispatch(
thunkActionCreator() );
从thunk的源码中可以看到,dispatch和getState方法分别赋给了param1 和param2(函数作用域链)。

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信