初探redux,了解中间件原理
在知乎上通过若川视野分享的文章跟着读了一下redux的源码,原文地址:https://zhuanlan.zhihu.com/p/148303595。
跟着分享的步骤调试过程还是很顺利的,而且讲解的也比较清楚。
记录一下刚开始没想明白的几个点。
1、createStore过程的理解
在没有使用中间件的情况下,该方法执行完相关的验证逻辑和初始化内容之后直接返回如下方法:
如果使用中间件,会通过enhancer方法返回增强之后的store,从源码可以看到enhancer方法来源于两个地方:1、通过参数传入;2、实际上就是在传入中间件之后,中间件返回的结果被赋值给了enhancer,然后enhancer通过传入createStore以及reducer返回增强之后的store对象。
2、compose方法理解
compose这个方法难理解的部分主要是就是这里:
return funcs.reduce(function (a, b) { return function (...args) { return a(b(...args)); }; });
此处是利用闭包原理实现的,我是通过以下方式理解的:
假设funcs是这样的[fn1, fn2, fn3],funcs里面为中间件的个数,执行逻辑是这样的,
第一次a为fn1,b为fn2,可以记录为result1 = fn1(fn2(...args)),
第二次a为result1,b为fn3,可以记录为result2 = result1(fn3(...args))
最后通过createStore返回的store.dispatch实际上就是第一个中间件fn1的返回结果,然后依次执行fn2,fn3,直至最初始的dispatch。
fn1中的next是fn2,fn2中的next是fn3,fn3中的next是初始的dispatch。
3、applyMiddleware执行过程的理解
返回一个匿名函数,该函数的参数为createStore,applyMiddleware在执行过程中会先执行createStore,然后对dispatch进行处理,利用compose方法对中间件进行连接返回新的dispatch以及store。
4、ensureCanMutateNextListeners方法的作用
该方法比较简单,如果当前的listeners和下一个是相同的,则切断他们的引用关系。项目中可以利用数组的slice方法改变数组的引用关系,以免后续修改数组导致其他的数据引起不必要的问题。
if (nextListeners === currentListeners) { nextListeners = currentListeners.slice() }