# Redux Saga

## 简述
- Reducers负责处理action的state更新;
- Sagas负责协调那些复杂或异步的操作。

## 安装

npm install --save redux-saga

```
// ...
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

// ...
import { rootSaga } from './sagas'

const sagaMiddleware = createSagaMiddleware()
const store = createStore(
reducer,
applyMiddleware(sagaMiddleware)
)
sagaMiddleware.run(rootSaga)

const action = type => store.dispatch({type})

```
## 辅助函数

用来在一些特定的action被发起到Store时派生任务。

1. takeEvery
2. put: 用于创建dispatch Effect
3. take: 通过全面控制action观察进程来构建复杂的控制流
4. fork: 无阻塞调用

---

```
yield fetch(url) => yield call(fetch, url)

```
### take
等待dispatch匹配某个action
```
while(true) {
yield take('Click_Action')
yield fork(clickButtonSaga)
}
```

### put
触发某个action,作用和dispatch相同
```
yield put({type: 'CLICK'})
```

```
//具体例子
import { call, put } from 'redux-saga/effects'

export function* fetchData(action) {
try {
const data = yield call(fetch, url)
yield put({type: 'FETCH_SUCCESS', data})
} catch (error) {
yield put({type: 'FETCH_FAILED', error})
}
}
```
### call
有阻塞的调用saga或者返回promise的函数,只在触发某个动作

### takeEvery
循环监听某个触发动作,通常会使用while循环替代
```
import {takeEvery} from 'redux-saga/effects'

function* watchFetchData() {
yield takeEvery('FETCH_REQUESTED', fetchData)
}
```
### takeLatest
对于触发多个action的时候,只执行最后一个,其他的会自动取消
```
import { takeLatest } from 'redux-saga/effects'

function* watchFetchData() {
yield takeLatest('FETCH_REQUESTED', fetchData)
}
```
### fork和cancel
通常fork和cancel配合使用,实现非阻塞任务,take是阻塞状态,也就是实现执行take的时候,无法继续向下执行,fork是非阻塞的,同样可以使用cancel取消一个fork任务
```
function* authorize(user, password) {
try {
const token = yield call(Api.authorize, user, password)
yield put({type: 'LOGIN_SUCCESS', token})
} catch(error) {
yield put({type: 'LOGIN_ERROR', error})
}
}

function* loginFlow() {
while(true) {
const {user, password} = yield take('LOGIN_REQUEST')
yield fork(authorize, user, password)
yield take(['LOGOUT', 'LOGIN_ERROR'])
yield call(Api.clearItem('token'))
}
}
```
当执行yield fork(authorize, user, password),同时执行yield take(['LOGOUT', 'LOGIN_ERROR'])

### 错误处理
我们假设远程数据读取因为某些原因失败了,API函数API.fetch返回一个被拒绝(rejected)的Promise
```
import Api from './Api'
import { call, put } from 'redux-saga/effects'

// ...
function* fetchProducts() {
try {
const products = yield call(Api.fetch, '/products')
yield put({ type: 'PRODUCTS_RECEIVED', products })
} catch (err) {
yield put({ type: 'PRODUCTS_REQUEST_FAILED', err)
}
}
```

### takeEvery的使用
saga中的take并不支持action的循环调用,即遍历数组执行action,为解决该问题,可以使用takeEvery来执行action,此时即可实现遍历数组执行action。

```
import { call, put, takeEvery } from 'redux-saga/effects'

function* fetchUsr(action) {
const payload = action
try {
const user = yield call(api.getUser, payload)
yield put({ type: GET_ENTITIES_USER, user })
} catch (err) {
console.log('err: %o', err)
}
}

function* mySaga() {
//在每个 'GET_USER' action 被发起时调用 fetchUser
//允许并发(译注:即同时处理多个相同的 action)
takeEvery(actions.GET_USER, fecthUser)
}
```

Redux-Saga学习心得的更多相关文章

  1. redux saga学习

    来源地址:https://www.youtube.com/watch?v=o3A9EvMspig Saga的基本写法 takeEvery与takeLatest的区别 takeEvery是指响应每一个请 ...

  2. 我的MYSQL学习心得(一) 简单语法

    我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  3. 我的MYSQL学习心得(二) 数据类型宽度

    我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  4. 我的MYSQL学习心得(三) 查看字段长度

    我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  5. 我的MYSQL学习心得(四) 数据类型

    我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(五) 运 ...

  6. 我的MYSQL学习心得(五) 运算符

    我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  7. 我的MYSQL学习心得(六) 函数

    我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  8. 我的MYSQL学习心得(七) 查询

    我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  9. 我的MYSQL学习心得(八) 插入 更新 删除

    我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得( ...

  10. 我的MYSQL学习心得(九) 索引

    我的MYSQL学习心得(九) 索引 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

随机推荐

  1. 服务器数据库挂掉 Can 't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock '(2) ";

    刚刚遇到这个报错,我无语了,我这么个菜逼,咋解决,还好师兄(付付)解决了,付付真棒,在此记录一下,以供学习 Can 't connect to local MySQL server through s ...

  2. 使用java对文件批量重命名

    有时候从网络上下载的电视剧或者动漫,名字上都会被该网站加上前缀或者后缀,如图: 那么处女座的同学就不同意了,不行,我就是想让它按照我的习惯方式命名!但是呢,一个个修改是不是特别麻烦,如果是上百个呢?如 ...

  3. Listener与Filter

    一.监听器Listener javaEE的13们规范中 包括servlet技术和jsp技术 servlet规范中包括三门技术:(servlet的三大组件) servelt技术  Listener技术 ...

  4. 新鲜小玩意儿- deviceOrientation移动设备旋转事件

    <javascript高级程序设计>第三版 其中事件的章节 提到一个有意思的事件 deviceOrientation 也就是 设备(device) - orientation(方向) 贴代 ...

  5. Maven学习(三)

    maven相关概念 maven坐标 Maven世界拥有大量构建,当我们需要引用依赖包是,需要用一个用来唯一标识去确定唯一的一个构建.如果拥有了统一规范,就可以把查找工作交给机器. 类似于空间找点的坐标 ...

  6. javaWeb学习总结(6)- 会话之cookie技术

    什么是会话? 在日常生活中,从拨通电话到挂断电话之间的一连串的你问我答的过程就是一个会话. 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为 ...

  7. java虚拟机学习-深入理解JVM(1)

    1   Java技术与Java虚拟机 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成: Java编程语言.Java类文件格式.Java虚拟机和Java应 ...

  8. Lua学习(2)——表达式

    1. lua算术操作符lua支持的算数操作符: + - * /除 ^指数 %取模 -符号 2. lua关系操作符 <小于 >大于 <= >= == ~=不等于 3. 逻辑操作符 ...

  9. 什么是ZigBee、Wifi无线技术?有什么优势?

    Zigbee:是基于IEEE802.15.4标准的低功耗个域网协议.根据这个协议规定的技术是一种短距离.低功耗的无线通信技术.这一名称来源于蜜蜂的八字舞,由于蜜蜂(bee)是靠飞翔和"嗡嗡& ...

  10. 日志组件二:log4j2

    一.背景 随着业务服务(Server App)逐渐增加,我们的业务系统中的日志输出面临的问题越来越多,高并发下对磁盘io这块消耗的越来越大,因此,急需要一个高性能且最好能够支持异步输出日志的日志框架, ...