RxJS

介绍: 解决异步事件。它将一切数据包括HTTP请求,DOM事件或者普通数据等包装成流的形式,然后利用强大丰富的操作符(Operators )对流进行处理,使得用户可以用同步编程的方式处理异步数据。

基本概念:Observable 类似于函数声明,subscribe类似于函数调用,调用时传入回调函数Observable 对象来执行,执行后的返回值称为Subscription ,可以停止后续Observable 的执行

Observable (可观察对象): 。是一可观察序列,简单来说数据就在Observable中流动,用户可以使用各种operator对流进行处理。

//create方法创建一个Observable
var observable = Observable.create(function(observer) { observer.next('Jerry'); observer.next('Anna');})// subscribe订阅 observable
console.log('start');
observable.subscribe(function(value) {console.log(value);
})
console.log('end');// 输出
start
Jerry
Anna
end

Observer (观察者): 一个回调函数的集合,它知道如何去监听由 Observable 提供的值,其包括以下三个方法
Next – 表示数据正常流动,没有出现异常
Error – 表示流中出错,可能是运行出错,http报错等
Complete – 表示流结束,不再发射新的数据

1、 要使用观察者,需要把它提供给Observable的subscribe方法。
2、 在一个流的生命周期中,error和complete只会触发其中一个,可以有多个next(表示多次发射数据),直到complete或者error。

  console.log('just before subscribe');const observe = {next: x => console.log('got value ' + x),error: err => console.error('something wrong occurred: ' + err),complete: () => console.log('done'),};// 订阅这个 observable// 只有在订阅之后,才会在流Observable变化的时候,调用observer提供的方法,并通知它observable.subscribe(observe);console.log('just after subscribe');// 输出just before subscribegot value 1got value 2got value 3just after subscribegot value 4done

Subscription (订阅): 表示 Observable 的执行,Subscription基本上只有一个unsubscribe()函数,这个函数用来释放资源或取消Observable执行,清理由Subscription占用的资源。

let subscription = observable.subscribe(observe);setTimeout(() => {subscription.unsubscribe();}, 1000);

Operators (操作符):
操作符是Observable类型上的方法,用来处理集合。当操作符被调用时,它们不会改变已经存在的Observable实例。相反,它们会返回一个新的Observable,它的subscription逻辑基于第一个Observable。


其实部分操作符从功能来讲可能会觉得区别不太大,区分起来也比较困难,我们可以查阅它们的弹珠图来方便我们区分。

结合vue-rx的使用

安装并配置vue-rx的依赖包

yarn add rxjs
yarn add vue-rx
//main.js文件
import VueRx from "vue-rx";
Vue.use(VueRx);

vue-rx会新增一个钩子函数subscriptions,和vue的data类似的使用;以及用来存放事件的一个domStreams数组

事件的使用:

<template><ul><li v-for="(num, index) in numList" :key="index" v-stream:click="{subject: getNum$,data: {'index': index,'num': num}}">{{ num }}</li></ul><p>点击的数字为:{{ num$.index }}</p><p>点击的数字下标为:{{ num$.num }}</p>
</template>
<script>import { Observable } from 'rxjs'export default {name: 'HelloWorld',data () {return {numList: [1, 2, 3]}},domStreams: ['getNum$',],subscriptions() {return {num$: this.getNum$// 从传入的对象中获取key为data的value,传入下一个operator.pluck('data').map(data => data)// 因为视图引用了num$.index,所以这里要初始化num$为对象,避免报错.startWith({}) }}
</script>

关于switchMap、concatMap、exhaustMap的使用:

domStreams: ['getConcatMapCount$', 'getSwitchMapCount$', 'getExhaustMapCount$'],
subscriptions() {return {// 当你连续点击按钮多次获取数据时,cancatMap会将获取到的数据按队列发出concatMapCount$: this.getConcatMapCount$.concatMap(e => {return new Observable.from(this.getCount());}),// 当你连续点击按钮多次获取数据时,switchMap只会将最后一个点击发出的值发出,前面发出的值会被吞掉switchMapCount$: this.getSwitchMapCount$.switchMap(e => {return new Observable.from(this.getCount());}),// 当你连续点击按钮多次时,exhaustMap仅执行一次,在第一次值发出后,才可以继续点击下一次发出值exhaustMapCount$: this.getExhaustMapCount$.exhaustMap(e => {return new Observable.from(this.getCount())})}},methods: {getCount() {return new Promise((resolve, reject) => {this.count ++;setTimeout(() => {resolve(this.count);}, 1000);})}}

关于forkJoin的使用:

会在每个被合并的流都发出结束信号时发射一次数据,也就是只触发一次回调
 methods: {getEmergencyMapData() {const $viewData = queryEmergencyViewMapData(this.$route.query.id).pipe(map(data => [data]),catchError(() => {return of([]);}));const $viewData2 = queryEmergencyIconpointMapData(this.$route.query.id).pipe(map(data => [data]),catchError(() => {return of([]);}));const $viewData3 = queryEmergencyDecisionMapData(this.$route.query.id).pipe(map(data => [data]),catchError(() => {return of([]);}));//同时发送三个请求,将返回值组成一个新的数组forkJoin($viewData, $viewData2, $viewData3) .pipe(map(([view1, view2, view3]) => [...view1, ...view2, ...view3])tap(data => {console.log(data )})).subscribe(); //在methods中必须订阅了才会发送请求}}

结合vue-rx, Akita的使用

Akita介绍: Akita是一种基于RxJS的状态管理模式,它采用Flux中的多个数据存储和Redux中的不可变更新的思想,以及流数据的概念,来创建可观察的数据存储模型。

Akita的使用:
安装并配置Akita的依赖包

yarn add @datorama/akita

在src下新建store文件,目录结构如下

xxx.store.js: 存放所要管理的状态

import { createStore } from "@datorama/akita";const initialState = {//存放ui展示的变量,一般为布尔值UI: {isShowPlanPanel: false, //预案详情},//存放其他变量,字符串,数组,对象等selectPlanId: null, //预案id//层级比较复杂的地图对象viewer: null
};export const basisDataStore = createStore(initialState, {name: "basisData"
});

xxx.service.js: 操作store数据的方法的集合,比如对该数据的修改、增加、删除等等

import { basisDataStore } from "./basis-data.store";export function isShowPlanPanel(show) {basisDataStore.update(state => ({...state,UI: { ...state.UI, isShowPlanPanel: show }}));
}
export function setSelectPlanId(id) {basisDataStore.update(state => ({...state,selectPlanId: id}));
}/**** @param {*} viewer 更新地图viewer*/
export function updateViewer(viewer) {mapStore.update(state => {return {...state,viewer};});
}
/*** 获取地图viewer* 可以不通过xxx.query.js文件,直接通过getViewer获取viewer对象,但不能监听其变化*/
export function getViewer() {return mapStore.getValue().viewer;
}

xxx.query.js: 将store数据暴露给外部,方便组件的调用

import { createQuery } from "@datorama/akita";
import { basisDataStore } from "./basis-data.store";export const basisDataQuery = createQuery(basisDataStore);export const $isShowPlanPanel = basisDataQuery.select(state => state.UI.isShowPlanPanel
);
export const $selectPlanId = basisDataQuery.select(state => state.selectPlanId);

参数传递的顺序依次是:

1.、组件A调用service.js的方法,为selectPlanId和isShowPlanPanel赋值

 import {setSelectPlanId,isShowPlanPanel} from "../../store/basis-data/basis-data.service";onClickRow(row) {isShowPlanPanel(true);setSelectPlanId(row.id);}

2、组件B在subscriptions钩子函数中监听selectPlanId和isShowPlanPanel的变化

import { $selectPlanId } from "../../store/basis-data/basis-data.query";
subscriptions() {return {isShowPlanPanel: $isShowPlanPanel,planData: $selectPlanId.pipe(mergeMap(planId => queryPlanDetails(planId )),//发送请求,获取详情map(data => {if (data) {//数据处理...return data}}))};},

RxJS结合vue-rx, Akita的介绍和使用相关推荐

  1. 基于Vue的Quasar Framework 介绍 这个框架UI组件很全面

    基于Vue的Quasar Framework 介绍 这个框架UI组件很全面 基于Vue的Quasar Framework 中文网 http://www.quasarchs.com/ quasarfra ...

  2. vue使用,及指令介绍,计算属性/过滤器

    目录 Vue是什么 vue的单页面原理 Vue的使用 指令介绍: v-if和 v-show的区别 v-on 事件绑定: v-bind 绑定属性 处理数组绑定 v-model双向数据绑定 created ...

  3. 【vue作业】vue实现海贼王网页介绍--动漫网站设计

    1.引言 你是否有过相关设计结课作业,课程设计无处下手,网页要求的总数量太多?没有合适的模板?数据库,java,python,vue,html作业复杂工程量过大?毕设毫无头绪等等一系列问题.你想要解决 ...

  4. Vue前端组件库介绍

    kb-vue-components 组件库平台介绍 这里汇集大家常用的Vue组件, 并提供相应组件的使用教程. 方便你找到适合自己的组件,并快速上手使用. 开源项目地址: kb-vue-compone ...

  5. Vue 防抖节流 详细介绍(面试常客、去繁从简、性能优化)

    本文主要介绍js中的防抖和节流以及在vue项目中如何使用它们来达到性能优化的目的. 前置知识点:js.闭包.es6.vue等. 使用背景: 很多场景下,页面具有交互性,免不了会触发一些事件以及发送一些 ...

  6. java英语单词学习网站 Vue项目源码介绍

    本软件是一款高智能化的英语学习软件,具备查阅复习内容,复习进度,以及复习提醒等功能:还需具有复习汇总等功能.用户可无限扩充自己的词库,能随心所欲地制作出适合自己的词库,达到快速记单词,读音,词义的效果 ...

  7. Vue后台管理系统模板介绍

    介绍:Vue.js 是一个目前比较流行的前端框架,今天给大家推荐几款基于 Vue 的后端管理的框架.目前比较流行和 Vue 搭配的 UI组件 有Element-UI.iview.Bootstrap-V ...

  8. vue项目结构目录介绍

    一:目录结构介绍 二:项目介绍 build 文件夹 及 子目录 这里面是一些webpack的配置,主要用于项目打包时的一些设置.这里不去更详细的深入,相关的文件及配置会在后面用到时在详细的介绍. co ...

  9. Vue项目目录结构介绍(三)

    前言 本章我们会对一个 Vue 项目的目录结构进行讲解,解释各子目录以及文件的作用,前端的模块化,Vue 单文件组件规范等. 1.基础目录和文件介绍 在上一章,我们通过 vue-cli 创建了一个新的 ...

最新文章

  1. python中构造方法可以被继承吗_python – 类继承:构造函数应该兼容吗?多重继承的情况?...
  2. JAVA 边界布局管理器
  3. MST(最小生成树)的构造
  4. arcgis 4.x graphicslayer点击事件_ArcGis中X、Y值的巧用方法小记
  5. 3d max用不同目标做关键帧_3D动画制作流程大解析
  6. KGDiscreetAlertView
  7. “狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
  8. 免费还能商用的视频素材,拿走不谢。
  9. 计算机cpu intel,intel CPU后面带F是什么意思?Intel处理器后面带“F”含义详解
  10. 区块链十年一梦:有人辞官归故里,有人星夜来赶考
  11. appdesigner生成exe文件并转移至不上网机
  12. 转载:一个程序员的顿悟
  13. c执行cmd pdf2swf_SWFTOOLS PDF2SWF 参数详解
  14. rsync同步+inotify实时同步部署
  15. 抖音视频突然播放量少了很多,抖音限流怎么查看?
  16. python绘制动态心电图_东软医院收费端使用手册.doc
  17. iterm 主题颜色配置
  18. day21-办公自动化:利用Python发邮件
  19. 20190724杭电多校第二场
  20. 数仓第5篇:『数据魔法』ETL

热门文章

  1. 全国统考英语计算机多少分及格,远程教育统考英语考试合格分数线标准如何
  2. MFC exe文件生成的图标更改方法
  3. WSL与WIN怎么互通有无?
  4. LTSPICE使用教程:参数变量和参数扫描
  5. 【超简单PR学习】用pr制作一个电子相册
  6. ES6的Lambda表达式
  7. Winpcap 动态链接库调用npf.sys
  8. 量子力学 Schrodinger 方程的简单导出
  9. 2. Fortran的Hello world-开始Fortran的编程
  10. 简历,求职求项目,硕士-4年工作经验-2年管理经验