rx学习

我们先了解rxjs的使用原理,在了解他的实现方法。

#### 如果理解observable构造函数中的next和你执行subscrible中的next呢。你在构造函数中调用的next就是subscrible中的next。你多次的subscrible就会多次执行构造函数,多次的next方法也是不同的。

### 如何理解rxjs的单播和多播。

 

只有一个observer可以播的我们称之为单播,Observable没有next属性的。每次subscribe执行一次构造函数,每次的observer都是不同的。

 #### subject使用中如何把observable的单播转为了多波。

多波subject订阅了单播,从而使单播变为了多播。

observable subscrible那个subject对象,通过subject多播的内容都会通知到observable中。

 

 

#### 原来的observable虽然是可以有多个subscrible,但是接听到的next值是不同的,或者说因为执行了两遍构造函数。所以他们监听的是两个observer两个对象。

 

#### subject的实现机制。

用一个代码的代理的subject(多一个addobserver的方法)

然后当执行一个observable的next的时候,会通知到 subject的next会执行注册的。

 

### 因为网上的中文文档大豆基于rxjs5的所以我们使用的时候也使用5.

静态操作符和对象操作符。

静态操作符可能有多个数据,对象操作符可能只有一个输入。 

#### 如果处理异步和同步 ,如果订阅传回的observer。

 

#### rxjs的引入方式。

 #### rxjs 6的改变。

导入的方式改变了。这个很重要。很多原来链式操作现在变为了operation操作。

https://blog.csdn.net/weixin_41404460/article/details/83110952

https://segmentfault.com/a/1190000014956260?utm_source=channel-hottest

#### 触发rxjs的next两种方法。

在angular中,一个serviceA类。

主要注入了providers 中,那么构造函数就会执行一次。

如果父模块注入了serviceA,子模块也注入了serviceA,那么子模块会继承父构造器中的this下的属性。

执行一次subscribe,那么new Observable() 中传入的函数就会执行一次。

new Observable出来的对象还没有next方法。

 #####  ??? 为什么,Observable注册了一个subscrible和unsbucrible的方法,但是new出来的对象就可以多次subscrible,oberver的next是直接调用注册的subscrible中的next么。到底是哪个subscrible调用哪个subscrible哪个next调用哪个next.

 

####  更多的关于   多播的可观察对象

多播的可观察对象
一个“多播”通过可能有许多订阅者的 Subject 传递通知,而普通的“单播”仅仅传递通知给一个单独观察者。

一个多播的 Observable 使用一个 Subject,使多个 Observers 看到相同的 Observable 执行。

在内幕,这是多播操作器的工作原理:Observers 订阅基础 Subject,Subject 订阅 Observable 源。

以下示例类似于上一个使用 observable.subscribe(subject) 的示例:

点击运行

var subject = new Rx.Subject();

var source = Rx.Observable.interval(1000).take(5)

var connectableObservable = source.multicast(subject);

var observerA = {
  next: function (x) { console.log('A next: ' + x); },
  error: function (err) { console.log('A error: ' + err); },
  complete: function ( ) { console.log('A done'); }
}

connectableObservable.connect();// 包含有 source.subscribe(subject)

connectableObservable.subscribe(observerA);// 相当于 subject.subscribe(observerA)

var observerB = {
  next: function (x) { console.log('B next: ' + x); },
  error: function (err) { console.log('B error: ' + err); },
  complete: function ( ) { console.log('B done'); }
}

setTimeout(function ( ) {
  connectableObservable.subscribe(observerB);// 相当于 subject.subscribe(observerB)
}, 2000)
multicast 返回一个 ConnectableObservable,它看起来像一个普通的 Observable,但在订阅时就像一个 Subject。

ConnectableObservable 是一个具有 connect() 方法的 Observable。

connectableObservable.connect(); 告诉共享的 Observable 什么时候开始执行。因为 connect() 在源代码下有 source.subscribe(subject),connect() 返回一个 Subscription,你可以取消订阅,以取消共享的 Observable 执行。

如下例,将在 2 秒之后执行 Observable 。

var subject = new Rx.Subject();

var connectableObservable = Rx.Observable.interval(1000).take(5).multicast(subject);

var observerA = {
  next: function (x) { console.log('A next: ' + x); },
  error: function (err) { console.log('A error: ' + err); },
  complete: function ( ) { console.log('A done'); }
}

connectableObservable.subscribe(observerA);

var observerB = {
  next: function (x) { console.log('B next: ' + x); },
  error: function (err) { console.log('B error: ' + err); },
  complete: function ( ) { console.log('B done'); }
}

setTimeout(function ( ) {
  connectableObservable.connect();
  connectableObservable.subscribe(observerB);
}, 2000)
停止 Observable 执行共享 点击运行下例:

var connectableObservable = Rx.Observable.interval(1000)
  .do(x => console.log('Source ' + x))
  .multicast(new Rx.Subject());

var observerA = {
  next: function (x) { console.log('A next: ' + x); },
  error: function (err) { console.log('A error: ' + err); },
  complete: function ( ) { console.log('A done'); }
}

connectableObservable.connect(); // start

var subA = connectableObservable.subscribe(observerA);

var observerB = {
  next: function (x) { console.log('B next: ' + x); },
  error: function (err) { console.log('B error: ' + err); },
  complete: function ( ) { console.log('B done'); }
}

var subB;
setTimeout(() => {
  subB = connectableObservable.subscribe(observerB);
}, 2000)

setTimeout(() => {
  subA.unsubscribe();
  subB.unsubscribe();
  console.log('unsubscribe both');
}, 5000)
输入如下:

"Source 0"
"A next: 0"
"Source 1"
"A next: 1"
"Source 2"
"A next: 2"
"B next: 2"
"Source 3"
"A next: 3"
"B next: 3"
"Source 4"
"A next: 4"
"B next: 4"
"unsubscribe both"
"Source 5"
"Source 6”
...
可以看到,全部订阅取消之后, Observable 依然一直执行。

connectableObservable.connect() 会返回一个 subscription。

因为 conncect 调用是使用 observable.subscribe(subject),然后再给 observer 传播值。所以停止所有订阅的办法,就是取消订阅 connectableObservable.connect() 返回的 subscription。

点击运行

var connectableObservable = Rx.Observable.interval(1000)
  .do(x => console.log('Source ' + x))
  .multicast(new Rx.Subject());

var observerA = {
  next: function (x) { console.log('A next: ' + x); },
  error: function (err) { console.log('A error: ' + err); },
  complete: function ( ) { console.log('A done'); }
}

var sub = connectableObservable.connect(); // start

var subA = connectableObservable.subscribe(observerA);

var observerB = {
  next: function (x) { console.log('B next: ' + x); },
  error: function (err) { console.log('B error: ' + err); },
  complete: function ( ) { console.log('B done'); }
}

var subB;
setTimeout(() => {
  subB = connectableObservable.subscribe(observerB);
}, 2000)

setTimeout(() => {
  sub.unsubscribe();
  console.log('unsubscribe shared subscription');
}, 5000)
引用计数 - refCount

调用 connect() 手动和处理订阅通常很麻烦。通常,我们希望在第一个 Observer 到达时自动连接,并在最后一个 Observer 取消订阅时自动取消共享执行。

请考虑以下示例,其中按照此列表概述的进行订阅:

第一个观察者订阅多播的 Observable
多播的 Observable 已连接 (connect)
接着 next 值0传递到第一个 Observer
第二观察者订阅多播的 Observable
next 值1被传递到第一个 Observer
next 值1被传递到第二个 Observer
第一个 Observer 从多播的观察者取消订阅
next 值2被传递给第二个 Observer
第二个 Observer 从多播的观察者取消订阅
与多播的 Observable 的连接已取消订阅
为了实现这个显式调用 connect(),我们写下面的代码:

点击运行

var source = Rx.Observable.interval(500);
var subject = new Rx.Subject();
var multicasted = source.multicast(subject);
var subscription1, subscription2, subscriptionConnect;

subscription1 = multicasted.subscribe({
  next: (v) => console.log('observerA: ' + v)
});
// We should call `connect()` here, because the first
// subscriber to `multicasted` is interested in consuming values
subscriptionConnect = multicasted.connect();

setTimeout(() => {
  subscription2 = multicasted.subscribe({
    next: (v) => console.log('observerB: ' + v)
  });
}, 600);

setTimeout(() => {
  subscription1.unsubscribe();
}, 1200);

// We should unsubscribe the shared Observable execution here,
// because `multicasted` would have no more subscribers after this
setTimeout(() => {
  subscription2.unsubscribe();
  subscriptionConnect.unsubscribe(); // for the shared Observable execution
}, 2000);
如果我们希望避免对 connect() 的显式调用,我们可以使用 ConnectableObservable 的 refCount() 方法(引用计数),它返回一个 Observable,跟踪它有多少订阅者。当订阅者数量从0增加到1时,它将为我们调用 connect(),启动共享执行。只有当订阅者数量从1减少到0时,它将完全取消订阅,停止进一步执行。

refCount 使多播的 Observable 在第一个用户到达时自动开始执行,并在最后一个用户离开时停止执行。

下面是一个例子:

点击运行

var source = Rx.Observable.interval(500);
var subject = new Rx.Subject();
var refCounted = source.multicast(subject).refCount();
var subscription1, subscription2, subscriptionConnect;

// This calls `connect()`, because
// it is the first subscriber to `refCounted`
console.log('observerA subscribed');
subscription1 = refCounted.subscribe({
  next: (v) => console.log('observerA: ' + v)
});

setTimeout(() => {
  console.log('observerB subscribed');
  subscription2 = refCounted.subscribe({
    next: (v) => console.log('observerB: ' + v)
  });
}, 600);

setTimeout(() => {
  console.log('observerA unsubscribed');
  subscription1.unsubscribe();
}, 1200);

// This is when the shared Observable execution will stop, because
// `refCounted` would have no more subscribers after this
setTimeout(() => {
  console.log('observerB unsubscribed');
  subscription2.unsubscribe();
}, 2000);
refCount() 方法只存在于 ConnectableObservable 上,它返回一个 Observable,而不是另一个 ConnectableObservable。

多次使用 multicast subject

点击运行

var subject = new Rx.Subject();

var shared = Rx.Observable.interval(1000).take(3).multicast(subject).refCount();

var observer = {
  next: (a) => console.log(a)
}

var subA = shared.subscribe(observer)

setTimeout(() => {
  var subB = shared.subscribe(observer); // 这里不会再有值,因为 3 秒的时候 subject 已经 complete 。
}, 4000)
点击运行

var subjectFactory = () => {
  return new Rx.Subject();
}

var shared = Rx.Observable.interval(1000).take(3).multicast(subjectFactory).refCount();

var observer = {
  next: (a) => console.log(a)
}

var subA = shared.subscribe(observer)

setTimeout(() => {
  var subB = shared.subscribe(observer);
}, 4000)


// subA : --0--1--2|
// subB --0--1--2|


 

posted @ 2019-04-13 17:17  飘然离去  阅读(305)  评论(0编辑  收藏  举报