1.生成saga中间件

a.通过sagaMiddlewareFactory工厂函数生成sagaMiddleware并将之返回
b.在生成中间件时默认情况下,context为{}, channel是由stdChannel函数生成, sagaMonitor为空
c.生成中间件就是redux的中间件,用户dispatch时会先经过中间件,在saga中间件会先调用其他中间件(通过next(action)),之后执行channel.put(action)来通知信道中处于监听状态的effect执行。

2.stdChannel生成标准信道

a.此函数内部调用的是同文件的multicastChannel函数,只是将生成的chan的put方法进行了二次封装。
b.multicastChannel(多播信道)内部维护currentTakers和nextTakers共同指向的一个任务队列。
    b1.multicastChannel函数返回一个对象,对象中包含put、take、close三个用于操作内部队列的函数和一个MULTICAST为true的标识符。
    b2.take函数用于将callback函数(任务)放入任务队列中,并给callback函数函数绑定[MATCH]属性(默认都是() => ()=> true )和cancel方法(从队列中移除该callback函数)
    b3.put函数将任务队列中(take放入的callback)任务循环执行,输入为dispatch的action
    b4.close函数,循环执行,与put类似,只是输入为 { type: CHANNEL_END_TYPE }

3.sagaMiddleware.run

a.内部调用的boundRunSaga函数,该函数为生成saga中间件是声明的,而这个函数是将runSaga函数绑定(context, channel, dispatch, getState, sagaMonitor, options)参数得。
    a1.在调用runSaga函数时传入了effects的监听入口,saga(一个generate函数);将传入saga执行一次获得该函数的迭代器iterator,将iterator和其他参数(channel, getState, sagaMonitor,dispatch,finalizeRunEffect)传入proc并执行proc。
        注意:dispatch是通过wrapSagaDispatch包裹redux的dispatch得到的(给调用时传入的action绑定了SAGA_ACTION变量,值为{ value: true });finalizeRunEffect = v => v
    a2.将runEffect赋值给finalRunEffect函数,调用newTask创建一个主任务(内部维护一个任务的queue并有addTask等方法),调用一次next方法后,将task返回
    a3.next方法为传入的迭代器的自动执行函数,根据传入参数执行不同操作,无参数直接执行iterator的next函数,如返回的done为false,则执行digestEffect函数, 如果done为true则调用mainTask的cont函数。
    a4.digestEffect将传入的cb(上面的next)函数包装(所有cb函数都只能实行一次,再次执行时发现已经执行完成则直接返回),调用finalRunEffect(默认为runEffect)函数。
    a5.runEffect判断传入的effect(next中执行迭代器后result.value)类型,如果是promise则调用resolvePromise(effect, currCb);如果为迭代器iterator(说明执行的也是个generator函数)则调用proc穿件一个子任务进程,如果为effect(含有[IO]属性)则根据effect的type从effectRunnerMap中映射出对应的执行函数并执行,执行时把(env, effect.payload, currCb(只执行一次的上面的next), executingContext(包含task和digestEffect))传入。
b.effectRunnerMap:
    b1.select: runSelectEffect, 直接调用传入的getState并通过传入select映射出需要的属性。
    b2.take: runTakeEffect, 调用传入channel的take方法将传入cb放入channel信道中。
    b3.put: runPutEffect, 封装一个根据是否传入channel判断调用channel.put或redux的dispatch的函数放入调度asp()队列,并将整个asp队列中任务全部执行。
    b4.call: runCallEffect, 调用传入的fn函数,如果fn执行结果为promise的话执行resolvePromise;如果为迭代器iterator的话,执行proc生成一个子进程;否则直接调用cb将执行结果传入。
    
    
    

4.其他:

a.matchers是用来配置之后dispatch的action的。      

牛刀杀鸡
3 声望0 粉丝

下一篇 »
操作系统学习