What is Redux Saga
# What is Redux Saga
是一个用于管理应用程序 Side Effect(副作用,例如异步获取数据,访问浏览器缓存等)的 library,它的目标是让副作用管理更容易,执行更高 效,测试更简单,在处理故障时更容易。 Redux Saga = Saga Pattern + Redux Saga Middleware + ES6 Generator Yield
# Saga Pattern
处理LLT(Long Live Transaction)的一种组织管理方式,表示如何处理事物Ti以及回滚Ci之间的协作关系,不同于TCC(Try Confirm Cancel) (opens new window)模式,其相对实现会复杂一些,这些都是如何实现最终一致性的方式方法。 Note: original pager (opens new window)
# Redux Saga Middleware
通过提供一系列API来完成管理Side Effect的功能。 这些API包括阻塞和非阻塞等方式:
Name | Is Block |
---|---|
takeEvery | No |
takeLatest | No |
takeLeading | No |
throttle | No |
retry | Yes |
take | Yes |
put | No |
putResolve | Yes |
put(channel, action) | No |
call | Yes |
apply | Yes |
cps | Yes |
fork | No |
spawn | No |
join | Yes |
cancel | No |
select | No |
actionChannel | No |
flush | Yes |
cancelled | Yes |
race | Yes |
all | Blocks if there is a blocking effect in the array or object |
# ES6 Generator
继承于Iterator,实现的语法是function*返回Generator类型,外部可通过.next()等方式调用,返回结构是{ value: object, done: boolean}
Note:区别于C#语言的Generator 本质上都是可迭代的函数,不同点在于返回类型不同,Javascript Generator返回{ value: object, done: boolean },C#返回IEnumerator对象。在使用方式上也由于返回类型不同而不同,JS中可使用next函数传递信息给Generator,yield接收next传入的参数。
# ES6 Async/Await
其本质是Promise的语法糖 特性:
- Async内部可有Await实现,返回类型是Promise
- 同样可以通过Promise.All[P1,P2]实现并行操作
- 简化Then回调写法
# Promise本质
JS Promise是PromiseA+的一个实现,同样实现的还有Q.js, RSVP.js等非JS原生Library。
# Promise A+ Specification
一个异步操作的标准,规定了如何使用和返回类型,但没有表明实现细节。来源于Promise/A proposal (opens new window)
# Promise Flow
# How to use Redux Saga Middleware
# Where is saga
Redux: action - reducer, Redux Saga: action - saga - action - reducer
# Begin to use
- Define Sagas
import { call, put, takeEvery } from 'redux-saga/effects'
import API from './fetchUserAPI';
function* fetchUser() {
try {
const user = yield call(API.fetchUser);
yield put({type: "USER_FETCH_SUCCEEDED", user: user});
} catch (e) {
yield put({type: "USER_FETCH_FAILED", message: e.message});
}
}
function* mySaga() {
yield takeEvery("USER_FETCH_REQUESTED", fetchUser);
}
export default mySaga;
2
3
4
5
6
7
8
9
10
11
12
13
14
- Register Sagas
const sagaMiddleware = createSagaMiddleware();
export const store = createStore(
RootReducers,
applyMiddleware(
sagaMiddleware
)
);
sagaMiddleware.run(mySagas);
2
3
4
5
6
7
8
- Call action
export const getUser = () => {
return {
type: "USER_FETCH_REQUESTED"
};
};
2
3
4
5
6
# More Reading
Yield in C# and Javascript: http://luiscubal.blogspot.com/2013/12/comparison-of-two-worlds-await-and.html
ES6 Generator: https://exploringjs.com/es6/ch_generators.html
ES6 Standard Generators: http://www.ecma-international.org/ecma-262/6.0/#sec-generatorfunction-objects
ES6 Standard Async/Await: https://www.ecma-international.org/ecma-262/8.0/#sec-async-function-definitions
Deep in Async/Await: https://www.jianshu.com/p/b9a519b74cf2