总以为文章也应该是有生命力的,欢迎关注个人Github上的博客,这里的文章会依据我本人的见识,逐步更新。html
大多redux
的初学者都会使用redux-thunk
中间件来处理异步请求,其理解简单使用方便(具体使用可参考官方文档)。我本身其实也一直在用,最近偶然发现其源码只有一个函数,考虑到其在Github上至今有6747个赞,所以比较好奇它究竟给出了一个怎么样的函数。react
thunk
?在看具体的源码以前,咱们先看一个词thunk
,理解这个词有助于咱们理解源码。git
A thunk is a function that wraps an expression to delay its evaluation.
维基百科中是这样解释thunk
的:thunk
是一种包裹一些稍后执行的表达式的函数。github
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;
redux-thunk
的源码很是简洁,出去空格一共只有11行,这11行中若是不算上}
,则只有8行。最后三行模块的导出方法很好理解,express
// thunk的内容以下 ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); } // thunk.withExtraArgument的结果以下 function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }; }
thunk.withExtraArgument
容许给返回的函数传入额外的参数,它比较难理解的部分和thunk
同样,以下:redux
({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }
上述代码使用函数参数的解构加上连用三个箭头函数,显得很是简洁,单同时也带来了理解的困难(这也是箭头函数的缺点之一)。把上述代码在babel REPL中转译为ES5语法后,咱们看到如下结果:babel
"use strict"; function createThunkMiddleware(extraArgument) { return function (_ref) { var dispatch = _ref.dispatch, getState = _ref.getState; return function (next) { return function (action) { if (typeof action === "function") { return action(dispatch, getState, extraArgument); } return next(); }; }; }; }
这下,代码一会儿咱们能看懂了,不过稍等这里的dispatch
,getState
,next
还有action
又是什么?app
咱们先看看,在reudx
中咱们如何使用中间件:异步
let store = createStore( reducer, applyMiddleware(thunk) );
看来,要解开dispatch
,getState
,next
,action
从哪里来,咱们还须要再看看applyMiddleware
的源码,以下:函数
export default function applyMiddleware(...middlewares) { return (createStore) => (...args) => { const store = createStore(...args) let dispatch = store.dispatch let chain = [] const middlewareAPI = { getState: store.getState, dispatch: (...args) => dispatch(...args) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } }
能够看出其中middleware
执行时传入的参数对象middlewareAPI
中确实包含getState
和dispatch
两项,next
则来自dispatch = compose(...chain)(store.dispatch)
这一句中的store.dispatch
,而action
在dispatch
某个action
时传入。
通常来讲一个有效携带数据的action
是以下这样的:
{ type: ADD_TODO, text: 'Build my first Redux app' }
加入redux-thunk
后,action
能够是函数了,依据redux-thunk
的源码,咱们能够看出若是传入的action
是函数,则返回这个函数的调用,若是自己传入的函数是一个异步函数,咱们彻底能够在函数调用结束后,获取必要的数据再次触发dispatch
由此实现异步效果。
redux-thunk
的源码总的来讲仍是很简单的,理解这个函数自己并不难,可是在完全弄懂每一项却须要对reudx
的部分源码有所了解。react官方文档中的Middleware一节讲解的很是好,也确实帮我理解了中间件的工做原理,很是推荐阅读。以前一直使用redux-thunk
作异步处理,这段时间尝试了一下redux-saga
,它很是优雅,可用于处理更加复杂的异步action,以后有时间会再总结一下它的用法,若是能够,也愿意再分析下它的源码,欢迎关注。