RxJS的秘密 Observable 可观察对象

前言

最近因为Angular2了解到了RxJS这个东西,总的来说,RxJS的出现也是为了解决异步回调的,它针对于事件序列。

RxJS是一个通过使用可观察序列来构建异步和基于事件的程序的库。它提供了一个核心类型:Observable、卫星类型(大概是这些类型均围绕于Observable,也就是Observable是根基,而这些是辅助类型):Observer、Schedulers、Subjects)和操作符-衍生自一些数组方法,使得我们可以把异步事件以集合的方式进行处理。
把RxJS当做一个针对事件的Lodash(一个JS库)。
ReactiveX将观察者模式与迭代器模式和使用集合的函数式编程组合在一起,来满足这种管理事件序列的理想方式。

begin

环境搭建

typescript + webpack 完成前端环境搭建
这里写图片描述
上述是我的项目目录树
src用来保存源文件,dist用来保存编译好的输出的文件

下面是我的webpack配置文件 webpack.config.js

const webpack = require('webpack');
module.exports = {
    entry:__dirname + '\\src\\main.ts',
    output:{
        filename:"main.js",
        path:__dirname + "\\dist"
    },
    plugins:[
        new webpack.HotModuleReplacementPlugin()
    ],
    //loaders
    module:{
        rules:[
            {
                loader:'json',
                test:'/\.json$/'
            }
        ]
    },
    devServer:{
        contentBase:"./dist/",
        historyApiFallback:true,
        inline:true,
        hot:true,
        por们接下来要用到的webpack-dev-server

Observable

Observable 被翻译过来是可观察对象,它实现了观察者模式,我们可以用最常用的方法(用observable
create方法)来
创建一个Observable对象。

在此之前,你必须保证你正确安装了Rxjs,使用npm安装rxjs,对于npm项目的搭建这里就不必大费口舌了。

npm install --save--dev rxjs

首先,需要引入Rx模块

import * as Rx from 'rxjs/Rx'

之后我们可以创建一个observable

let observable = Rx.Observable.create(observer => {
    observer.next(1);
    observer.next(2);
    observer.next(3);
    observer.complete();
});

之后我们可以订阅它,observable就跟它的名字一样,是一个可观察对象,在观察者模式中,我们通常把它叫做被订阅者,两者意思都是一样的。现在我们来创建一个观察者

let observer = {
    next:data => console.log(`get a data , the data is ${data}`),
    error:err => console.log(JSON.stringify(err)),
    complete:() => console.log(`complete`)
}

然后我们再来订阅这个observable对象,使用subscribe方法进行订阅,将观察者对象传递进去

observable.subscribe(observer);

之后我们运行webpack-dev-server。

webpack-dev-server --inline

在浏览器的console看到以下的输出信息

1
2
3
complete

next , error ,complete方法是属于观察者的,next决定传递一个什么样的数据给观察者,如果过程中有发生错误,就会产生一个error对象,发射过去,complete代表整个处理(dispose)过程已经完毕。

例如我们在complete下面再次发射一个数值4,观察者却收不到整个消息。

let observable = Rx.Observable.create(observer => {
    observer.next(1);
    observer.next(2);
    observer.next(3);
    observer.complete();
    observer.next(4);
});

看到控制台打印的结果:

1
2
3
complete

creating Observables

上面我们调用了Observable的静态方法create进行创建,返回一个Observable对象,除此之外,RxJS还提供了了很多的更快捷的创建方法,比如:

let observable = Rx.Observable.from([1,2,3,4,5]);

from方法接受一个数组为参数,在该observable被订阅时,该数组里的内容都会被发射出去。

observable.subscribe(x => console.log(`this data is ${x}`));

output:

1
2
3
4
5

下面来做一个更加常见的例子。

经常与DOM交互中,避免不了订阅DOM事件。

订阅button的click事件

let btn = document.querySelector('button');
btn.addEventListener('click',e => {
  console.log('cliked');
});

而在Observable中,你可以这样做。

import * as Rx from 'rxjs/Rx'

let btn = document.querySelector('button');

Rx.Observable.fromEvent(btn,'click')
    .subscribe(e => {
        console.log('clicked');
    });

Subscribe Observable

订阅Observable是RxJS编程中比较常见的操作。

我们先来看一下前面是如何创建一个Observable的。

let observable = Rx.Observable.create(observer => {
  obserber.next(1);
});

很显然,这里create方法里的参数传递了一个observer,这个observer实际上就是观察者对象。这里传入create方法里的是一个匿名的函数。如果不匿名,它可能是这样的。

let observable = Rx.Observable.create(function subscribe(observer){
  obserber.next(1);
});

它实际上是subscribe方法,当我们调用observable的subscribe方法时,它会把对应的数值发射到对应的观察者对象上,也就是说,各个观察者对象是相互独立的。

let subscription1 = observable.subscribe(x => console.log(`listener1 : get a data is ${x}`));
let subscription2 = observable.subscribe(x => console.log(`listener2 : get a data is ${x}`));

output :

1
1

Execute Observable

前面说了Observer(订阅者)最主要的方法就是next , error 和complete。

next负责发送一个数据给观察者

error是封装异常对象然后发送给观察者

complete表示已经执行完毕

但是在实际的开发中,我们捕获异常最好是用传统的try catch语句,然后发送异常对象

let observable = Rx.Observable.create(function subscribe(observer){
  try{
    observer.next(1);
    throw new Error('this is a test');
  }
  catch(e){
    observer.error(e);
  }
});

subscribe

observable.subscribe(x => console.log(`the data is ${x}`),err => console.log(`have a err , the err object is ${JSON.stringify(err)}`));

Dispose Observable

最后我们需要了解如何取消订阅。比如我们有一个每一秒向观察者发送一个值的Observable

let observable = Rx.Observable.create(observer => {
    let i = 0;
    setInterval(() => {
        observer.next(i++);
    },1000);
})

下面订阅它 , 我们会看到每秒打印的数值

observable.subscribe(x => console.log(x));

output :

0
1
2
3
4
...

现在我们想要在第一个值打印完毕之后不再接着打印后面的值,这个的解决办法有两种

1.添加complete方法

我们只需修改一下create方法,就能实现这个效果了,因为complete方法执行完毕后,后面的值都不会发射

let observable = Rx.Observable.create(observer => {
    let i = 0;
    setInterval(() => {
        observer.next(i++);
        observer.complete();
    },1000);
})

output :

0

2.执行unsubscribe方法

调用observable的subscribe方法返回的是一个subscription对象,它有一个unsubscribe方法可以取消订阅

因此,我们可以这样做

let observable = Rx.Observable.create(observer => {
    let i = 0;
    setInterval(() => {
        observer.next(i++);
    },1000);
})
let subscription = observable.subscribe({
    next:x => console.log(`the data is ${x}`),
    error:err => console.log(`have a err , the err object is ${JSON.stringify(err)}`)
});

setTimeout(() => {
    subscription.unsubscribe();
},1100);

可以看到console的打印

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值