摘要:在调用函数时传入了的监听入口,一个函数将传入执行一次获得该函数的迭代器,将和其他参数,,,,传入并执行。调用传入的函数,如果执行结果为的话执行如果为迭代器的话,执行生成一个子进程否则直接调用将执行结果传入。
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的。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/106165.html
摘要:在函数式编程中,异步操作修改全局变量等与函数外部环境发生的交互叫做副作用通常认为这些操作是邪恶肮脏的,并且也是导致的源头。 注:这篇是17年1月的文章,搬运自本人 blog... https://github.com/BuptStEve/... 零、前言 在上一篇中介绍了 Redux 的各项基础 api。接着一步一步地介绍如何与 React 进行结合,并从引入过程中遇到的各个痛点引出 ...
摘要:通过创建将所有的异步操作逻辑收集在一个地方集中处理,可以用来代替中间件。 redux-saga框架使用详解及Demo教程 前面我们讲解过redux框架和dva框架的基本使用,因为dva框架中effects模块设计到了redux-saga中的知识点,可能有的同学们会用dva框架,但是对redux-saga又不是很熟悉,今天我们就来简单的讲解下saga框架的主要API和如何配合redux框...
摘要:举例来说一个异步的请求场景,可以如下实现任何异步的逻辑都可以,如等等也可以使用的和。实际上在中,一个就是一个函数。 书籍完整目录 3.4 redux 异步 showImg(https://segmentfault.com/img/bVyou8); 在大多数的前端业务场景中,需要和后端产生异步交互,在本节中,将详细讲解 redux 中的异步方案以及一些异步第三方组件,内容有: redu...
摘要:通过可以实现很多有趣的简洁的控制。这里默认使用到了的一个特性,如果某一个任务成功了过后,其他任务都会被。组合是的内关键字,使用的场景是一个。 书籍完整目录 3.5 compose redux sages showImg(https://segmentfault.com/img/bVyoVa); 基于 redux-thunk 的实现特性,可以做到基于 promise 和递归的组合编排,而...
阅读 3477·2023-04-25 19:56
阅读 1589·2021-11-12 10:36
阅读 1738·2021-11-08 13:19
阅读 1501·2019-08-30 14:06
阅读 2992·2019-08-30 11:01
阅读 1671·2019-08-29 13:23
阅读 2668·2019-08-29 11:18
阅读 3382·2019-08-26 13:35