使用方法
1 | function counter(state = 0, action) { |
createStore
1 | function createStore(reducer, preloadedState, enhancer) { |
- 接受三个入参,如果传入了enhancer,那么会直接返回
enhancer(createStore)(reducer, preloadedState)
- subscribe的关键代码就是把listener加入队列
- dispatch就是把listeners里的所有回调挨个执行
- 其还实现了observable方法,为了就是给一些observable/reactive的库使用,是的,他们可以监听这个store的变化
中间件是怎么实现的
原理
applyMiddleware
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50function applyMiddleware() {
for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) {
middlewares[_key] = arguments[_key];
}
return function (createStore) {
return function () {
var store = createStore.apply(void 0, arguments);
var _dispatch = function dispatch() {
throw new Error('Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.');
};
var middlewareAPI = {
getState: store.getState,
dispatch: function dispatch() {
return _dispatch.apply(void 0, arguments);
}
};
var chain = middlewares.map(function (middleware) {
return middleware(middlewareAPI);
});
_dispatch = compose.apply(void 0, chain)(store.dispatch);
return _objectSpread2({}, store, {
dispatch: _dispatch
});
};
};
}
function compose() {
for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {
funcs[_key] = arguments[_key];
}
if (funcs.length === 0) {
return function (arg) {
return arg;
};
}
if (funcs.length === 1) {
return funcs[0];
}
return funcs.reduce(function (a, b) {
return function () {
return a(b.apply(void 0, arguments));
};
});
}关键方法就是compose方法,把传入的middleware串联起来,并且是从右往左执行
- applyMiddleware返回的其实是一个修改了dispatch的enhancer,入参是createStore。把初始的dispatch方法传入到compose后的middlewares,拿到处理后的dispatch替换原始store的方法。
怎么写一个middleware
1 | function logger({ getState }) { |
- 可见middleware是函数,返回值是一个以dispatch为入参的函数。所以applyMiddleware中要把所有middleware先执行一遍,然后再compose
redux-promise-middleware原理
1 | function middleware({ dispatch } = {}) { |
- 如果action.payload是一个promise的话,先dispatch一个pending状态的action,然后执行promise.then,并在其handleFulfill/handleReject中再dispatch相应的action,所以reducer中就可以根据promise的状态来写对应的处理函数