关于 RxJS redux-observable

问题1:这个东西有什么用,为什么要用它?

redux-observable 作为redux 的一个中间件提供了action 异步处理的能力,并且它基于RxJS,RxJS 是一个强大的库,熟悉Angular 应该不会陌生。如果对RxJS 没有兴趣,那么redux-observable 也没必要去了解了。

为什么要用它呢?个人认为:1 喜欢并熟悉RxJS,2 redux-observable 完全接管所有数据请求操作,通过 dispatch 指定action 进行异步数据步操作。也就是说大部分数据请求、数据的处理逻辑写在redux-observable 的 epics中。这样做有点类似angular 中的 【服务】 概念,简单的说就是将业务逻辑和组件分离,组件只负责数据展示,至于数据如何处理怎么来的不是组件应该关心的,组件只负责展示与收集数据。服务概念参见:https://www.angular.cn/guide/architecture-services

Angular 把组件和服务区分开,以提高模块性和复用性。 通过把组件中和视图有关的功能与其他类型的处理分离开,你可以让组件类更加精简、高效。

 问题2: 说的天花乱坠各种好,怎么用?

说到底,redux-observable 是redux 的一个中间件,具体代码和使用中间件是一样的,如果熟悉redux 不难理解。epic 是redux-observable 中的一个概念,具体的定义参见官方文档,简单的说就是一个触发器,它不会拦截 action  action 会顺利的抵达被reducer处理。当指定的一个或几个action 被dispatch时 ,epic 进行异步的操作,比如去请求数据,当数据返回时,再dispatch 指定的action 去更新redux state。所以一个项目会有很多epic ,它有一个类似combineReducers 的方法 combineEpics 将众多epic 合成一个rootEpic。combineEpics 和combineReducers 是有区别的它不能嵌套使用(ps:个人愚见,官网demo 没看到像combineReducers 一样的嵌套使用 )。

说了这么多,epic 核心还是RxJS的使用,如果对RxJS 不熟悉建议还是去翻翻文档吧。

正常的一个请求服务端数据的epic大致是这样的。

  1. 发送数据前 一个loading 状态
  2. 请求数据成功时 将数据处理完毕 更新redux state,有时一个请求可能要dispatch 多个action
  3. 可能会取消请求
  4. 请求数据错误(注意不是非200报错)处理
  5. 请求报错,可能是服务端报错也可能是数据处理时报错控制
  6. 请求完成时,去掉loading

官网还是有一些demo 的 但是不是很全,比如第2、1、4、6,

先贴代码

import {of, concat} from 'rxjs';
import {mergeMap, map, catchError, finalize} from 'rxjs/operators';
import {ofType} from 'redux-observable';
import {FETCH_SUB_SITE_LIST, FETCH_MARKER_DATA, FETCH_OTHER_INFO, Actions} from "../redux/actions";
import {Ajax} from "../http.service";
import {message} from 'antd';
import {store} from "../redux";

export const getSubSiteListEpic = (action$: any, state$: any) => action$.pipe(
    ofType(FETCH_SUB_SITE_LIST),
    mergeMap((action) => {
        const {value: {map: {main: {warehouseId}}}} = state$;
        return concat(
            of(Actions.updateLoadingStatus(true)),
            Ajax.post('/api/getSubSiteList', {warehouseId}).pipe(
                map(({response: {code, msg, data}}) => {
                    if (code !== 0) {
                        throw Error(msg);
                    }
                    const tempMap: any = {};
                    const temp = data.map((v: any) => {
                        tempMap[v.siteId] = v.districtList;
                        return {
                            label: v.siteName,
                            value: v.siteId
                        }
                    });

                    store.dispatch(Actions.updateDistrictMap(tempMap)); // 更新district 与子站映射
                    return Actions.updateSubSiteList(temp); // 更新子站列表
                }),
                catchError(({message: err}: any) => {
                    message.error(err);
                    return of(Actions.updateErrFetch(err))
                }),
                finalize(() => {
                    store.dispatch(Actions.updateLoadingStatus(false));
                })
            )
        )
    })
);

 http.server.ts

export class Ajax {
    static post(url: string, data?: any, method?: string) {
        return race(
            of({response:{code:408,msg:'请求超时!'}}).pipe(delay(50000)),
            ajax.post(`${baseURL}${url}`, data, {
                'Content-Type': 'application/json',
                'token': sessionStorage.getItem('token')
            }),
        );
    }
}

具体代码参见:git@github.com:yyccmmkk/wms-map-react.git

具体RxJS API参见官方文档。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值