原版redux-saga是为了解决redux异步流的方案,既然是插件的插件,在使用的时候就应该像黑盒一样,不管你内部是怎么运作的,我的输入输出方式不会有太大改变,这就要先引出redux的中间件middleWare

middleWare的作用:在调用异步方法时,通过中间件处理,完成异步请求后再由中间件调用原生dispatch完成,给人的感觉就像使用原生dispatch一样简洁

  • MiddleWare

要引入中间件就要去解析原版的MiddleWare干了啥,首先从createStore入手,在原版redux中引入中间件的代码如下

const store = createStore(reducer, applyMiddleware(sagaMiddleware));

作为createStore的第二个参数传入一个applyMiddleware()的执行结果,目前我们还不知道applyMiddleware这个函数的执行结果是什么,但是可以确定的是不影响createSrore()创建出来还是store这个结果

那么applyMiddleware到底干了什么,这时候我们参考一下源码后发现其实就是对dispatch进行了一次封装,然后又将“皮球”踢给了createStore,这也正符合我们对中间件的描述

applyMiddleware返回一个函数,这个函数在createStore被调用,并且返回值被作为store返回

源码考虑的很周到,对异常情况做了处理,感叹redux源码的简洁强大!虽然代码很简洁,不过第一次看还是觉得很抽象,在了解了大致流程了后就可以写一个类似功能的函数,并且完成createStore的改造

这里就通过compose完成了dispatch的封装

  • compose

compose的源码及其简洁巧妙,这里我们借用一下原版compose

理解起来也不是很难,结合在applyMiddleware中的调用

const dispatch = compose(...funcs)(store.dispatch);

这里compose对middle的数量进行分类判断,无中间件,那么直接返回原版dispatch,然后就是有中间件的情况,由于reduce本身的原因,一个中间件直接返回middleWare(middleWareAPI),这里也可以猜测middleware本质上也是个函数,接受原本的api方法,然后返回一个二次封装的dispatch

至于后面这个reduce调用,针对2个及以上中间件,完成了所有中间件dispatch的顺序调用,因为我们还记得dispatch(action)返回的结果是action本身,所以这里这个循环嵌套调用可以这样理解

dispatch(dispatch(dispatch(dispatch( dispatch(action) = action ))))

每一层dispatch就代表一个中间件的调用,而每一次调用的返回值为action,又作为下一层dipatch的传入参数,最后会得到一个多层嵌套的dispatch

function DISPATCH(action){
return dispatch(((((...action...)))))
}

在applyMiddleware()()最后将store解构进一个新对象,将原版dispatch替换,返回作为新的store

整个过程在createStore中完成并返回

这样就完成了middleWare中间件的引入

  • My-Redux-Saga

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注