对Rxjs Observable的理解与心得总结

创建Observable:

Rx.Observable.create 是 Observable 构造函数的别名,它接收一个参数:subscribe 函数。
例子:每秒推送一个“Hi”

Rx.Observable.create(function subscribe(observer){
var i=setInterval((observer)=>{
observer.next("Hi")
},1000);
});

在上面的示例中,subscribe 函数是用来描述 Observable 最重要的一块。

订阅Observable:

示例中的 Observable 对象 observable 可以订阅,像这样:

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

observable.subscribe 和 Observable.create(function subscribe(observer) {...}) 中的 subscribe 有着同样的名字,这并不是一个巧合。在库的实现中,这两个subscribe是不同的,但在实际使用中,你可以认为在概念上它们是等同的。

这个例子表明订阅行为在Observable 的多个观察者之间是不共享的。当使用一个观察者调用 observable.subscribe 时,Observable.create(function subscribe(observer) {...}) 中的 subscribe 函数就会为这个观察者运行一次。对 observable.subscribe 的每次调用都会触发针对给定观察者的独立设置。(每个已订阅的观察者都拥有 Observable 的独立执行)

以上简单的理解为:
订阅Observable的时候,需要传入一个observer。observer定义了自身的next、complete、error方法。observer的next方法会获得Observable的next方法推送过来的值,并按照自己的定义处理他们。当一个observer订阅Observable的时候,不会影响另外一个observer。(每个已订阅的观察者都拥有 Observable 的独立执行)
也就是说:只有Observable才可以被subscribe。只有observer才可以subscribe Observable。

订阅 Observable 像是调用函数, 并提供接收数据的回调函数。

取消订阅:

Observable.subscribe()返回一个Subscription对象。调用其unsubscribe()方法取消订阅。实现类似如下:

var observable = Rx.Observable.create(function subscribe(observer) {
  // 追踪 interval 资源
  var intervalID = setInterval(() => {
    observer.next('hi');
  }, 1000);

  // 提供取消和清理 interval 资源的方法
  return function unsubscribe() {
    clearInterval(intervalID);
  };
});

//这里返回一个函数声明
var subscription=observable.subscribe((x)=>console.log(x));
//执行取消订阅
subscription.unsubscribe();
Observer (观察者)

简单的讲,观察者是用来消费(处理)Observable 推送出来的值。
它是一个包含了3个方法的对象。每个方法分别对应一个Observable发送通知的类型。
如果你只提供了一个方法,但是没有将它附加到观察者对象上,像这样:

observable.subscribe(x => console.log('Observer got a next value: ' + x));

在 observable.subscribe 内部,它会创建一个观察者对象并使用第一个回调函数参数作为 next 的处理方法。
如果你没有提供某个回调函数,Observable 的执行也会正常运行,只是某些通知类型会被忽略,因为观察者中没有相对应的回调函数。

Subscription (订阅)

subscription通常只有一个unsubscribe()方法,这个函数用来释放资源或去取消 Observable 执行。
Subscription 还可以合在一起,这样一个 Subscription 调用 unsubscribe() 方法,可能会有多个 Subscription 取消订阅 。你可以通过把一个 Subscription 添加到另一个上面来做这件事:

subscription1.add(subscription2);//添加子订阅
subscription1.unsubscribe();// 2个都会取消订阅。
subscription1.remove(subscription2); //取消添加子订阅
Subject (主题)

什么是 Subject? - RxJS Subject 是一种特殊类型的 Observable,它允许将值多播给多个观察者,所以 Subject 是多播的,而普通的 Observables 是单播的(每个已订阅的观察者都拥有 Observable 的独立执行)。

  • Subject 像是 Observable,但是可以多播给多个观察者。Subject 还像是 EventEmitters,维护着多个监听器的注册表。

  • 每个 Subject 都是 Observable 。

在 Subject 的内部,subscribe 不会调用发送值的新执行。它只是将给定的观察者注册到观察者列表中,类似于其他库或语言中的 addListener 的工作方式。
  • 每个 Subject 都是观察者。

Subjects 是将任意 Observable 执行共享给多个观察者的唯一方式。
多播 Observable 在底层是通过使用 Subject 使得多个观察者可以看见同一个 Observable 执行。

多播的 Observables
  • 多播 Observable 在底层是通过使用 Subject 使得多个观察者可以看见同一个 Observable 执行。(共享一个Observable )

在底层,这就是 multicast 操作符的工作原理:观察者订阅一个基础的 Subject,然后 Subject 订阅源 Observable 。

var subject = new Rx.Subject();

subject.subscribe({
  next: (v) => console.log('observerA: ' + v)
});
subject.subscribe({
  next: (v) => console.log('observerB: ' + v)
});

var observable = Rx.Observable.from([1, 2, 3]);

observable.subscribe(subject); // 你可以提供一个 Subject 进行订阅

执行结果:
observerA: 1
observerB: 1
observerA: 2
observerB: 2
observerA: 3
observerB: 3


multicast 操作符返回一个 Observable,它看起来和普通的 Observable 没什么区别,但当订阅时就像是 Subject 。multicast 返回的是 ConnectableObservable,它只是一个有 connect() 方法的 Observable 。

var source = Rx.Observable.from([1, 2, 3]);
var subject = new Rx.Subject();
var multicasted = source.multicast(subject);

// 在底层使用了 `subject.subscribe({...})`:
multicasted.subscribe({
  next: (v) => console.log('observerA: ' + v)
});
multicasted.subscribe({
  next: (v) => console.log('observerB: ' + v)
});

// 在底层使用了 `source.subscribe(subject)`:
multicasted.connect();

connect() 方法十分重要,它决定了何时启动共享的 Observable 执行。因为 connect() 方法在底层执行了 source.subscribe(subject),所以它返回的是 Subscription,你可以取消订阅以取消共享的 Observable 执行。

Subject的三种变体类型:

  • BehaviorSubject :主要用来表示随着时间的流逝,值会改变的情况。比如生日是Subject,而生日就是BehaviorSubject。
  • ReplaySubject :当有新的订阅者订阅时,可以指定回放的值得个数,或者以 window time (以毫秒为单位) 规定范围内发生的值。
  • AsyncSubject : 当被观察者的值推送完成时,才将最后一个值发送给观察者。类似于last ()操作符。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,176评论 5 469
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,190评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,232评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,953评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,879评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,177评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,626评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,295评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,436评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,365评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,414评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,096评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,685评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,771评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,987评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,438评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,032评论 2 341

推荐阅读更多精彩内容