一.理解
redux-saga 就是用来处理副作用(副作用简单的理解为:异步操作)的一个中间件。它是一个接收事件,并可能触发新事件的过程管理者,为你的应用管理复杂的流程。redux-saga
是一个 redux 中间件,意味着这个线程可以通过正常的 redux action 从主应用程序启动,暂停和取消,它能访问完整的 redux state,也可以 dispatch redux action。
二.比较redux-thunk 和 redux-saga
redux-thunk 和 redux-saga 是 redux 应用中最常用的两种异步流处理方式。
(1).redux-thunk:redux-thunk 的任务执行方式是从 UI 组件直接触发任务。
redux-thunk 的主要思想是扩展 action,使得 action 从一个对象变成一个函数.
简单的列子:
import {
API_BUTTON_CLICK,
API_BUTTON_CLICK_SUCCESS,
API_BUTTON_CLICK_ERROR,
} from './actions/consts';
const getDataStarted = () => ({type: API_BUTTON_CLICK});
const getDataSuccess = data => ({type: API_BUTTON_CLICK_SUCESS, payload: data});
const getDataError = message => ({type: API_BUTTON_CLICK_ERROR, payload: message});
const getDataFromAPI = () => {
return dispatch => {
dispatch(getDataStarted());
axios.get('http://rest.learncode.academy/api/wstern/users')
.then((response) => {
dispatch({type: 'RECEIVE_USERS', payload: response.data})
})
.catch((err) => {
dispatch({type: 'FECTH_USERS_ERROR', payload: err})
})
}
}
Redux异步操作redux-thunk
Redux saga的写法:
import { call, put, takeEvery } from 'redux-saga/effects';
import {
API_BUTTON_CLICK,
API_BUTTON_CLICK_SUCCESS,
API_BUTTON_CLICK_ERROR,
} from './actoins/consts';
import { getDataFromAPI } from './api';
export function* apiSideEffect(action) {
try{
const data = yield call(getDataFromaAPI);
yield put({ type: API_BUTTON_CLICK_SUCESS, payload: data});
} catch(e) {
yield put({type: API_BUTTON_CLICK_ERROR, payload: e.message});
}
}
// the 'watcher' -on every `API_BUTTON_CLICK` action, run our side effect
export function* apiSaga() {
yield takeEvery(API_BUTTON_CLICK, apiSideEffect);
}
从上面看,我们可以知道,saga摆脱了返回方法或者promise链的麻烦,只简单用一个try-catch来处理任何的异步错误。然后put(或者dispatch)一个action来通知reducer。
最重要的是:sages 采用 Generator 函数来 yield
Effects(包含指令的文本对象)。Generator 函数的作用是可以暂停执行,再次执行的时候从上次暂停的地方继续执行。Effect 是一个简单的对象,该对象包含了一些给 middleware 解释执行的信息。你可以通过使用 effects API
如 fork
,call
,take
,put
,cancel
等来创建 Effect。( redux-saga API 参考)
三.redux-saga 使用
1.简单的使用 在react中:
index.js 中:
import { createStore, applyMiddleware} from 'redux';
import createSagaMiddleware from 'redux-saga';
import appReducer from './reducers';
import { helloSaga } from './sagas'
const sagaMiddleware = createSagaMiddleware();
const store = createStore(appReducer, applyMiddleware(sagaMiddleware));
//运行这个文件
sagaMiddleware.run(helloSaga) //输出Hello Sagas!
render(
,
document.getElementById('app')
);
//创建一个helloSaga.js文件
export function * helloSaga() {
console.log('Hello Sagas!');
}
2.Effects声明
Effects 来源于 dva 封装的底层库 redux-sagas 的概念,主要指的是处理 Side Effects ,指的是副作用(源于函数式编程),在这里可以简单理解成异步操作。
Reducers 的本质是修改 model 的 state,而 Effects 主要是 控制数据流程 ,所以最终往往我们在 Effects 中会调用 Reducers。
常用的操作:
1.put
用于触发 action 。
yield put({ type: 'todos/add', payload: 'Learn Dva' });
2.call
用于调用异步逻辑,支持 promise 。
const result = yield call(fetch, '/todos');
3.select
用于从 state 里获取数据。
const todos = yield select(state => state.todos);
3.redux-saga 的优点
(1)声明式 Effects:所有的操作以JavaScript对象的方式被 yield,并被 middleware 执行。使得在 saga 内部测试变得更加容易,可以通过简单地遍历 Generator 并在 yield 后的成功值上面做一个 deepEqual 测试。
(2)高级的异步控制流以及并发管理:可以使用简单的同步方式描述异步流,并通过 fork 实现并发任务。
(3)架构上的优势:将所有的异步流程控制都移入到了 sagas,UI 组件不用执行业务逻辑,只需 dispatch action 就行,增强组件复用性。
作者:Ruth92
链接:https://www.jianshu.com/p/e84493c7af35
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
三.参考
redux-saga
聊一聊 redux 异步流之 redux-saga