Redux-thunk原理探析

Redux-thunk原理探析

十一月 06, 2020

Redux的作用这里就不做过多赘述,简单看下Redux原理:

image

小tip:纯函数的核心理念在于:出参始终依赖于入参,不受外部的任何影响,也就是不会因为何时、何处调用而影响

可以很直观的看到,用户UI层面触发一系列的DOM事件,进而去dispatch action,将dispatch这个动作的处理交给reducer(纯函数)去做进一步处理。

Redux-thunk做了什么?

它是为了处理异步action的,因为在项目中难免会有异步请求数据,往redux中塞入获取的数据这样的动作。

但是,它究竟做了什么呢?

可以看看源码,一窥究竟:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 创建thunk-middleware
function createThunkMiddleware(extraArgument) {
// 拦截action
return ({ dispatch, getState }) => (next) => (action) => {
// 如果action为一个函数,那么就调用action,并且传入 dispatch、getState、extraArguement
if (typeof action === 'function') {
// 传入dispatch的目的是为了可以在action中去处理异步,在合适的时机dispatch
return action(dispatch, getState, extraArgument);
}
// 否则透传action
return next(action);
};
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

action的时候处理异步任务,在结束时,dispatch对应的reducer case

store组织

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { createStore, applyMiddleware }  from 'redux';
import thunk from 'redux-thunk';

export const asyncAdd = () => {
return (dispatch: (args: {type: any; payload?: any}) => void) => {
setTimeout(() => {
dispatch({ type: 'AsyncAdd', payload: 9})
}, 1000);
}
}

export const syncAdd = (payload: any) => {
return {
type: 'ADD',
payload
}
}

function reducers (state = { num: 1 }, action: any): any {
switch (action.type) {
case 'ADD':
return { ...state, num: action.payload } ;
case 'AsyncAdd':
return { ...state, num: action.payload } ;
default:
return state;

}
}

let store = createStore(reducers, applyMiddleware(thunk))


export default store;

End

thunk相似的工具还有saga,但是saga的设计更像是vuex中那样,把异步action剖离出来。利用了generator的写法,单独的saga文件去将异步同步化。

简单赘述一下Redux-saga处理流程:

先说明下Redux-MiddleWare的处理流程;

image

saga提供的effets会在处理完毕异步任务后,重新dispatch reducer中的action去更新store。监听用户action,将saga处理的异步action独立出来。

小Tip:什么是中间件?中间件是介于系统某几个部分的衔接应用,它可能只是简单地做一些数据交换任务,不处理业务逻辑,不处理底层硬件逻辑。