redux-saga学习笔记 川长思鸟来 2022-12-20 03:05 139阅读 0赞 官方文档:[https://redux-saga.js.org/][https_redux-saga.js.org] ## saga ## ![saga解释][saga] `redux-saga` 是 `redux` 的一个异步处理工具 相同的工具还有 `redux-thunk` 相比之下我觉得 `redux-thunk` 的上手难度比较低,`redux-saga` 本身的 `generator` 特性使异步的处理更加地优雅 -------------------- ## 组织方式 ## 在一个 `saga` 内部 ![saga内部组织][saga 1] `saga` 宏观布局 ![saga宏观布局][saga 2] -------------------- ## 宏观布局 ## ![saga宏观布局][saga 3] 某saga (事件) // worker saga function* loginHandle(action) { try { // 两个顺序异步请求 const res1 = yield call(LoginService.login, action.payload); const res2 = yield call(LoginService.getMoreUserInfo, res1); // 状态更新 yield put({ type: LOGIN_SUCCESS, payload: res2}); } catch (err) { yield put({ type: LOGIN_FAILURE, payload: err}); } } // watcher saga function* loginSaga() { yield takeEvery(LOGIN_SAGA, loginHandle); } export default loginSaga; 事件总线 import { all} from "redux-saga/effects"; import loginSaga from "./loginSaga"; export default function* rootSaga() { yield all([loginSaga()]); } Store import { loginReducer} from "./loginReducer"; import { createStore, combineReducers, applyMiddleware} from "redux"; import createSagaMiddleware from "redux-saga"; import rootSaga from "../action/rootSaga"; // step1. 创建saga中间件 const sagaMiddleware = createSagaMiddleware(); const store = createStore( combineReducers({ user: loginReducer}), // step2. 在创建的商店中应用 applyMiddleware(sagaMiddleware) ); // step3. 开始监听事件总线 sagaMiddleware.run(rootSaga); export default store; -------------------- ## 微观布局 ## ![saga微观布局][saga 4] 以下 API 均从 `redux-saga/effects` 导入 // eg. import { call, fork, put, take} from "redux-saga/effects"; **监听** * **takeEvery(类型,回调)** * **takeLatest(类型,回调)** 最后一次执行会终止上一次执行,和防抖类似 * **take(类型,回调)** 只执行一次 eg. // watcher saga function* loginSaga() { yield takeEvery(LOGIN_SAGA, loginHandle); } export default loginSaga; // 1.此处的 LOGIN_SAGA 就是 reducer 的 type // 2.对于需要用 saga 处理的 reducer, // 监听的地方和传统的 reducer不同, // saga 监听的对象单独拎出来放在以上API的第一个参数 `用其他 API 实现 takeEvery` const takeEvery = (pattern, saga, ...args) => call(function*() { while (true) { const action = yield take(pattern); yield fork(saga, ...args.concat(action)); } }); **执行** * **call** yield call(\[obj, obj.method\], arg1, arg2, …) `const products = yield call(Api.fetch, '/products')` * **fork** 用法和 `call` 类似,只是 `fork` 是非阻塞,而 `call` 是阻塞的 意思是如果某次 `call` 需要用到上一次的值,那就不能用 `fork` 了 * **apply** yield apply(obj, obj.method, \[arg1, arg2, …\]) * **cps** 用于处理组件回调 (这个地方官方没有给出实际例子,笔者目前也没有遇到过这样的场景,暂时举不出例子) eg. // worker saga function* loginHandle(action) { try { // 两个顺序异步请求 const res1 = yield call(LoginService.login, action.payload); const res2 = yield call(LoginService.getMoreUserInfo, res1); // 状态更新 yield put({ type: LOGIN_SUCCESS, payload: res2}); } catch (err) { yield put({ type: LOGIN_FAILURE, payload: err}); } } **派发** 一、`worker saga`的参数 function* fetchProducts (dispatch) { const products = yield call(Api.fetch, '/products'); dispatch({ type: 'XXX', products}); } 注意:官方并不推荐在生成器内部调用函数这种用法 二、`put` function* fetchProducts () { const products = yield call(Api.fetch, '/products'); yield put({ type: 'XXX', products}); } -------------------- 感谢你能看到这里~ [https_redux-saga.js.org]: https://redux-saga.js.org/ [saga]: /images/20221120/0ca13f9175094664af3ad7e9bf0ce370.png [saga 1]: https://img-blog.csdnimg.cn/20201110140130775.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1RNX0dvZHNwZWVk,size_16,color_FFFFFF,t_70#pic_center [saga 2]: https://img-blog.csdnimg.cn/2020111014022059.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1RNX0dvZHNwZWVk,size_16,color_FFFFFF,t_70#pic_center [saga 3]: https://img-blog.csdnimg.cn/20201110150505666.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1RNX0dvZHNwZWVk,size_16,color_FFFFFF,t_70#pic_center [saga 4]: https://img-blog.csdnimg.cn/20201110150527377.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1RNX0dvZHNwZWVk,size_16,color_FFFFFF,t_70#pic_center
相关 学习笔记 学习笔记 sudo adduser lilei sudo usermod -G sudo lilei sudo deluse 客官°小女子只卖身不卖艺/ 2022年11月26日 12:58/ 0 赞/ 6 阅读
相关 学习笔记 \ajax: 1、概念:异步的JavaScript 和 xml 1.1异步和同步:客户端和服务器端相互通信的基础上 \客户端必须等待服务器端的响应。在等待的期间客户 深藏阁楼爱情的钟/ 2022年10月29日 13:24/ 0 赞/ 264 阅读
相关 学习笔记 一. CSS 如何实现文字的垂直居中 1. 二.问题记录 1.创建新的JSP页面的时候报错:The superclass “javax.servlet.http.H 超、凢脫俗/ 2022年08月20日 09:30/ 0 赞/ 121 阅读
相关 【学习笔记】git学习笔记 使用git的好处 可以保存每个版本,只要在每个版本做完后进行上传 ![这里写图片描述][70] 可以异地读取更新 爱被打了一巴掌/ 2022年05月14日 09:10/ 0 赞/ 384 阅读
相关 学习笔记 我的第一天学习c\ 1、c\学习网址 [https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide 矫情吗;*/ 2022年05月08日 06:16/ 0 赞/ 306 阅读
相关 学习笔记 测试 ORM JPA EJB JPQL MOM JMS ORM 对象关系映射 英语:Object Relational M 爱被打了一巴掌/ 2022年02月16日 01:57/ 0 赞/ 380 阅读
相关 [笔记] Docker 学习笔记 1. 什么是 Docker > 官方文档:[链接][Link 1],中文文档:[链接][Link 2] Docker 属于 Linux 容器的一种封装,提供简单易用的容 缺乏、安全感/ 2021年11月27日 02:01/ 0 赞/ 563 阅读
相关 学习笔记 1、js如何将136分钟转化为几小时,几分钟 return (Math.floor(minutes/60) + "小时" + (minutes%60) + "分" 爱被打了一巴掌/ 2021年07月25日 23:46/ 0 赞/ 1028 阅读
还没有评论,来说两句吧...