说到中间件redux-saga,肯定会想起其他类似的redux-thunk、redux-promise,后俩者只是为了解决redux过程中异步网络加载问题,但它们并不会监听action,而redux-saga提供了take系列方法:take、takeEvery、takeLatest用来监听dispatch事件,有些人可能有些不明白,监听action是store的任务,redux-saga不是多管闲事吗!
其实这正是redux-saga的高明之处,试想,倘若把所有的逻辑处理都留给reducer,那得多乱!总得有个地方组织一下action的执行逻辑吧,比如上传图片这个功能,如果不用redux-saga,那么我们会这么操作:
function uploadImg(){
dispatch(准备上传);
try{
dispatch(上传成功);
}catch(){
dispatch(上传失败);
}
}
我们需要把这个上传逻辑写到响应事件中;
倘若我们使用redux-saga:
saga监听:dispatch(图片上传)
|
|
saga处理:uploadImg(),组织action完成逻辑处理
在saga中,我们监听一个大的action:上传图片,然后组织逻辑关系,去调用这些小的action去处理,最后返回结果,让功能处理更加有条理了!
API:
构造中间件:
createSagaMiddleware()
middleware.run(saga, ...args) 执行saga
saga辅助函数,是在 Effect 创建器的基础之上构建的(即高阶 API):
takeEvery 、takeLatest是一个高阶 API,使用 take 和 fork 构建完成。
Effect 创建器,创建一条 Effect 描述信息:
1、
put(action ) 发起一个 action, 执行是异步的,不会立即发生。
take(pattern) 等待 Store 上指定的 action。
select(state=>state.id)获取state,如果参数为空,则返回整个state;
2、call(function),function既可以是一个普通函数,也可以是一个 Generator 函数,middleware 调用这个函数并检查它的结果。
如果结果是一个 Generator 对象,middleware 会执行它,就像在启动 Generator (startup Generators,启动时被传给 middleware)时做的。 如果有子级 Generator,那么在子级 Generator 正常结束前,父级 Generator 会暂停。
如果结果是一个 Promise,middleware 会暂停直到这个 Promise 被 resolve,resolve 后 Generator 会继续执行。
3、
fork(function), 类似于 call,但 fork 的调用是无阻塞的,在等待 fn 返回结果时,middleware 不会暂停 Generator。 相反,一旦 fn 被调用,Generator 立即恢复执行。
fork返回结果结果是一个 task 对象(包含方法:task.isRunning()、task.result()、task.error()、task.done、task.cancel()):
join(task):指示 middleware 等待之前的 fork 任务返回结果;
cancel(task):指示 middleware 取消之前的 fork 任务,task同上;
Effect 组合器
race(effects):执行 多个 Effect,哪个先执行结束,则 race返回值就是哪一个结果。
[...effects] :并行执行多个 Effect,并等待所有 Effect 完成。
外部API
runSaga:将 Saga 连接至外部的输入和输出(即在外部执行 Saga),而不是 store 的 action。
另外,如果你不使用 Webpack 或 Browserify,umd 版本非常有用:
提示! 如果你的目标浏览器不支持 es2015 generators,那么你必须再使用一个可用的 polyfill,比如 babel 提供的:browser-polyfill.min.js。
其他方式导入:import 'babel-polyfill'