Redux-saga 基础学习

参考:

https://juejin.im/post/58eb4100ac502e006c45d5c9
<https://juejin.im/post/58eb4100ac502e006c45d5c9>

https://yanqiw.github.io/react/2017/03/05/redux-saga.html
<https://yanqiw.github.io/react/2017/03/05/redux-saga.html>

http://www.cnblogs.com/libin-1/p/6858558.html
<http://www.cnblogs.com/libin-1/p/6858558.html>

什么是Redux-saga

它是一个用于管理 Redux 应用异步操作
的中间件,通过创建 Sagas 将所有的异步操作逻辑收集在一个地方集中处理,像一个分散的支线在你的应用中单独负责解决异步的action(类似于后台运行的进程),从而代替 redux-thunk 中间件。

 

逻辑存在两个地方:

l  Reducers 负责处理 action 的 state 更新。

l  Sagas 负责协调那些复杂或异步的操作。

重要概念

副作用:


在action触发reduser之后执行的一些动作,这些动作包括但不限于,连接网络,io读写,触发其他action。因为Sage的副作用是通过redux的action触发的,每一个action,sage都会像reduser一样接收到。并且通过触发不同的action,
我们可以控制这些副作用的状态,例如,启动,停止,取消。所以,我们可以理解为Sage是一个可以用来处理复杂的异步逻辑的模块,并且由redux的action触发。

redux-saga提供了几种产生副作用的方式:主要用到了有两种takeEvery和takeLates。

takeEvery:会在接到相应的action之后不断产生新的副作用。
比如,做一个计数器按钮,用户需要不断的点击按钮,对后台数据更新,这里可以使用takeEvery来触发。

takeLatest:在相同的action被触发多次的时候,之前的副作用如果没有执行完,会被取消掉,只有最后一次action触发的副作用可以执行完。

 

 

Reduex能做:

l  调用一个异步函数;

l  发起一个 action 到 Store;

l  启动一个后台任务或者等待一个满足某些条件的未来的 action。

 

Effects

是一个 javascript 对象,里面包含描述异步动作的信息,可以通过 yield 传达给 sagaMiddleware 执行。

在 redux-saga 世界里,所有的 Effect 都必须被 yield 才会执行

 

常用API

call

用来调用异步函数,将异步函数和函数参数作为call函数的参数传入,返回一个js对象。saga引入他的主要作用是方便测试,同时也能让我们的代码更加规范化。

call操作是阻塞的,只有等promise回来后才能继续执行

fork

当调用fork启动一个任务时,该任务在后台继续执行,从而使得我们的执行流能继续往下执行而不必一定要等待返回。

 

 

put

作用和 redux 中的 dispatch 相同。

yield put({ type: 'CLICK_BTN' });

 

select

作用和 redux thunk 中的 getState 相同。

const id = yield select(state =>state.id);

调用put方法后,saga内部会分发action通知Store更新state。

 

take

等待 redux dispatch 匹配某个(由用户决定) pattern 的 action 。在执行顺序执行到take语句时才会相应action。

在genetator中使用take语句等待action时,generator被阻塞,等待action被分发,然后继续往下执行。

先等待一个按钮点击的 action ,然后执行按钮点击的 saga:

while (true) {

 yield take('CLICK_BUTTON');

 yield fork(clickButtonSaga);

}

 

 

阻塞调用和无阻塞调用

redux-saga 可以用 fork 和 call 来调用子 saga ,其中 fork 是无阻塞型调用,call 是阻塞型调用。

 

使用例子:

在用户提交表单的时候,我们想要做如下事情:

l  校验一些输入信息 (简单, 写在组件里)

l  弹起提示信息(写一个公用的提示信息模块,这样别的页面引入就可以用了)

l  提交后端服务 (直接组件里面fetch)

l  拿到后端返回状态 (promise实现)

l  隐藏提示信息 (给组建加一个控制属性)

l  更新redux store(dispatch咯。。。)

但是一旦涉及到多个表单提交,代码就会很长,重复代码很多。

用了redux-saga之后:

form组件触发提交action (一行简单的dispatch)

reducer这个action不需要自己处理

saga提交表单的副作用开始执行 (监听到触发副作用的action)

l  校验一下

l  通知显示层弹起信息框 (dispatch一下变更控制信息框弹起的store)

l  提交表单 (yield一个promis,yield是javascriptgenerator的语法,稍后有介绍)

l  拿到后端返回状态

l  更新redux store(dispatch一下)

 



使用了Saga后,react只负责数据如何展示,redux来负责数据的状态和绑定数据到react,而Saga处理了大部分复杂的业务逻辑。