在redux-observable中替换fetch请求网络数据
来源:互联网 发布:c语言指向函数的指针 编辑:程序博客网 时间:2024/06/10 23:40
通常在React项目中会搭配redux来管理React的state状态. 由于项目有异步action的需求, 并且后续会使用到rxjs, 同时想要action层面保持良好的纯字面量风格, 这时就考虑使用redux-observable提供异步action的支持.
目前项目中用到异步action的场景主要是接口的请求, 在接入redux-observable之前项目是使用isomorphic-fetch
来请求数据的, 接入中间件之后发现中间件本身的网络还是用的基于rxjs@5.x.x的ajax(XMLHttpRequest). 如果想用fetch来替换XMLHttpRequest在中间件中请求数据要怎么实现呢 ?
其实了解过fetch跟rxjs的特性的话应该会有思路. 首先中间件是通过执行Observable对象来支持异步aciton的, 其次fetch返回的是一个Promise对象, 而rxjs则可以把一个Promise对象包装成Observable对象. 那么我们按照这个套路把fetch包装到Observable对象里给epic方法使用是不是就能达到我们的目的了. 理论上来说是完全可行的, 那我们就以一个项目中的登录流程为例, 展示redux-observable + isomorphic-fetch的使用方式.
ACTION
因为使用了redux-observable中间件, 所以登录这个行为的action只是一个单纯的字面量. 发生登录行为时view直接dispatch该字面量就可以了.
/** * 登录action * @param account * @param pwd */export const loginAction = (account, pwd) => ({ type: ACTION_LOGIN, data: { account: account, password: md5(pwd) }});
代码跳转
Epic方法
在登录的epic方法中, 首先监听到action type为ACTION_LOGIN
的分发, 然后按照中间件的特性将网络请求的结果封进一个新的action中, 再次分发出去. 这里将实现放入了一个工具方法中, 参数则是新action的type, 网络请求需要的相关数据等.
/** * 登录 epic * @param action$ */export const loginEpic = action$ => action$.ofType(ACTION_LOGIN) .mergeMap(action => ajaxRequest({ actionType: ACTION_LOGIN_FULFILLED, method: AJAX_METHOD.POST, url: URL_LOGIN, params: action.data }));
代码跳转
ajaxRequest方法
在ajaxRequest方法中根据网络请求需要的参数构建出对应的Observable对象. 登录的调用是通过ajaxPost方法来构建的, 后面我们会说ajaxPost方法的实现. 当我们已经拿到Observable对象之后就要执行它并将结果或者异常以action的方式返回, 让epic方法重新dispatch出去.
/** * 提供给epic事件流使用, 根据参数构建request * @param requestParams {actionType, method, url, params} */export const ajaxRequest = requestParams => { const {actionType, method, url, params} = requestParams; let observable; switch (method) { case AJAX_METHOD.POST: observable = ajaxPost(url, params); break; case AJAX_METHOD.GET: observable = ajaxGet(url, params); break; case AJAX_METHOD.POST_FORM: observable = ajaxPostForm(AJAX_METHOD.POST_FORM, url, params); break; case AJAX_METHOD.POST_MULTI_FORM: observable = ajaxPostForm(AJAX_METHOD.POST_MULTI_FORM, url, params); break; default: observable = ajaxGet(url, params); } return observable.map(data => ({ type: actionType, data: data })).catch(e => Observable.of({ type: actionType, data: e }));};
代码跳转
ajaxPost方法
ajaxPost很简单, 就是根据场景和isomorphic-fetch
构建出application/json
类型的post请求. 并将该fetch方法返回的Promise对象经过buildRequestObservable方法的包装封成Observable对象返回给ajaxRequest用.
/** * post请求json内容, 返回Observable promise 对象 * @param url * @param params * @returns {Observable.<T>|*} */export const ajaxPost = (url, params) => { const content = JSON.stringify(params); const data = { method: AJAX_METHOD.POST, headers: { 'Authorization': `Bearer ${localStorage.token}`, "Content-Type": "application/json", "Content-Length": content.length.toString() }, body: content }; return buildRequestObservable(fetch(url, data));};
代码跳转
buildRequestObservable方法
buildRequestObservable方法对参数中传递进来的fetch Promise对象进行拆解, 做一些公共处理, 然后重新打包成一个新的Promise对象. 如果请求成功则解析出正常的业务数据, 根据情况进行回调. 否则将请求失败和异常的情况包装到错误包中给reject出来. 最后通过rxjs的转换方法将新的Promise对象转化成Observable对象.
/** * 根据fetch promise对象构建出一个Observable * @param fetch * @returns {Observable<T>|*} */const buildRequestObservable = fetch => { const request = new Promise((resolve, reject) => { fetch.then((response) => { if (!response.ok) { reject(buildErrorInfo(RES_FAILED, 'response code error')); } response.json().then((data) => { if (data.status === RES_SUCCEED) { resolve(data); } else { reject(data) } }); }).catch((e) => { reject(buildErrorInfo(RES_FAILED, e.toString())); }); }); return Observable.fromPromise(request);};
代码跳转
到这里就成功在使用redux-observable时替换ajax(XMLHttpRequest)为isomorphic-fetch
请求网络数据了. 由于我是对现有的系统进行进行改造的, 所以就没有用更加简单直接得代码Demo来展示, 顺便也分享一下这个CMS系统网络方面的设计, 同时也作为这个系统的文档之一. 项目Github地址: https://github.com/HiJesse/Demeter 欢迎交流.
转载请注明出处:http://blog.csdn.net/l2show/article/details/77444082
- 在redux-observable中替换fetch请求网络数据
- react-native(Fetch网络请求数据)
- Android中WebView拦截替换网络请求数据
- Android中WebView拦截替换网络请求数据
- Android中WebView拦截替换网络请求数据
- Android中WebView拦截替换网络请求数据
- Android中WebView拦截替换网络请求数据
- 在 JS 中使用 fetch 更加高效地进行网络请求
- 在 JS 中使用 fetch 更加高效地进行网络请求
- 在 JS 中使用 fetch 更加高效地进行网络请求
- ReactNative fetch 网络请求
- Fetch基本网络请求
- react-native网络请求Fetch中遇到的坑
- MVP+Retrofit+Observable+RecyclerView请求网络
- React-native fetch请求网络
- 高效网络请求之Fetch
- React Native Fetch网络请求
- Fragment 网络数据请求最好放在setUserVisibleHint中
- IOS 修改UITableview排序默认图标
- C++调用python脚本
- 以Alexnet为例说明solver文件的超参数
- 如鹏网学习笔记(十二)HTML5
- Mongodb ReplicaSet + Sharding集群实现
- 在redux-observable中替换fetch请求网络数据
- 8月19号CCPC——CaoHaha's staff(未解答)
- 浅谈js中==、!=、===、!==
- 关系型数据库与非关系型数据库的区别?
- 使用 vue 1.0.3 $set 函数遇到的坑
- Spring Boot开发问题(一.feignclient远程其他restful风格的项目时POST中)
- Qt程序只运行一个实例
- platform总线所有函数解析
- 姬风奇迹Season XI娱乐休闲一键版 (百度网盘/1.12G/服务端+客户端/更新赠品)