阅读 redux 源码之后,想要加深一下对中间件的理解,于是选择 redux-thunk(2.3.0)这个源码只有十几行的中间件。

之前 redux 的学习笔记 https://www.cnblogs.com/wenruo/p/9664375.html

redux 中的 applyMiddleware.js

export default function applyMiddleware(...middlewares) {
return createStore => (...args) => {
const store = createStore(...args)
let dispatch = () => {
throw new Error(
`Dispatching while constructing your middleware is not allowed. ` +
`Other middleware would not be applied to this dispatch.`
)
} const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
const chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch) return {
...store,
dispatch
}
}
}

每个中间件需要传入 store(只有 getState 和 dispatch)和 next(由上一个中间处理过的 dispatch)

在生成 dispatch 的时候 传入的  middlewareAPI 中的 dispatch 是一个只抛出异常的函数,用来提示在创建 dispatch 的时候, 中间件不应该使用 dispatch 。

创建后又将 dispatch 赋值为经过中间件生成的函数。这时

const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}

中 middlewareAPI.dispatch 就变成了最新的 dispatch 所以在中间件中可以使用 dispatch、

接下来可以看 redux-thunk 的源码

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;

使用时可以是 applyMiddleware(thunk) 或者 applyMiddleware(thunk.withExtraArgument(api))

如果是默认的 thunk 那么中间件的函数为

const thunk = ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState);
} return next(action);
};

如果是函数 就传入 dispatch 和 getState 否则就执行默认的 next

let store = createStore(reducer, applyMiddleware(thunk));
let action = (dispatch) => {
ajax(options).then((res) => {
dispatch({ type: 'change', content: res.data });
})
}
store.dispatch(action);

这样对于异步的操作就可以在 redux 中使用了~

最新文章

  1. 查看html元素绑定的事件与方法的利器
  2. oracle学习笔记系列------oracle操作例子的专用表
  3. nyoj 289 苹果 动态规划 (java)
  4. linux--杂记(rework)
  5. Fiddler学习之——对Android应用进行抓包
  6. 感受机房管理化繁为简-新款KVM使用心得
  7. Flex里的命名空间,fx、mx、s【转】
  8. iOS开发——使用技术OC篇&简单九宫格锁屏功能的实现与封装
  9. C#关于静态与非静态的区别
  10. [开心IT面试题] realloc用法
  11. vbscript multiple line syntax
  12. 阅读STL源码剖析之list
  13. 完美解决 Phonegap jQeuryMobile 闪屏 问题
  14. JQUERY1.9学习笔记 之基本过滤器(五) 大于选择器
  15. hdu 1426 Sudoku Killer ( Dancing Link 精确覆盖 )
  16. 远程连接mysql速度慢的解决方法
  17. OutputStream()
  18. Gym 101257G 24 (概率+二分)
  19. 这是您一直期待的所有iOS 11功能的屏幕截图
  20. 利用GCD 中的 dispatch_source_timer 给tableViewCell添加动态刷新的计时/倒计时功能

热门文章

  1. 关于for循环里面异步操作的问题
  2. Effective Java 第三版——43.方法引用优于lambda表达式
  3. 好代码是管出来的——Git的分支工作流与Pull Request
  4. Integer的疑惑
  5. Tomcat 优化方案 和 配置详解(转)
  6. 「CodeChef Dec13 REALSET」 Petya and Sequence 循环卷积
  7. 【BZOJ】1969: [Ahoi2005]LANE 航线规划
  8. BZOJ_3129_[Sdoi2013]方程_组合数学+容斥原理
  9. 钉钉机器人zabbix报警
  10. VMware workstation的基础使用