亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

RxJS 核心概念之Subject

weij / 2592人閱讀

摘要:返回的對(duì)象同時(shí)是類(lèi)型的,擁有方法。由于調(diào)用后,開(kāi)始執(zhí)行,因此,會(huì)返回一個(gè)供調(diào)用者來(lái)終止執(zhí)行。是的一個(gè)衍生類(lèi),具有最新的值的概念。舉一個(gè)形象的例子,表示一個(gè)人的生日,而則表示一個(gè)人的歲數(shù)。

什么是Subject? 在RxJS中,Subject是一類(lèi)特殊的Observable,它可以向多個(gè)Observer多路推送數(shù)值。普通的Observable并不具備多路推送的能力(每一個(gè)Observer都有自己獨(dú)立的執(zhí)行環(huán)境),而Subject可以共享一個(gè)執(zhí)行環(huán)境。

Subject是一種可以多路推送的可觀察對(duì)象。與EventEmitter類(lèi)似,Subject維護(hù)著自己的Observer。

每一個(gè)Subject都是一個(gè)Observable(可觀察對(duì)象) 對(duì)于一個(gè)Subject,你可以訂閱(subscribe)它,Observer會(huì)和往常一樣接收到數(shù)據(jù)。從Observer的視角看,它并不能區(qū)分自己的執(zhí)行環(huán)境是普通Observable的單路推送還是基于Subject的多路推送。

Subject的內(nèi)部實(shí)現(xiàn)中,并不會(huì)在被訂閱(subscribe)后創(chuàng)建新的執(zhí)行環(huán)境。它僅僅會(huì)把新的Observer注冊(cè)在由它本身維護(hù)的Observer列表中,這和其他語(yǔ)言、庫(kù)中的addListener機(jī)制類(lèi)似。

每一個(gè)Subject也可以作為Observer(觀察者) Subject同樣也是一個(gè)由next(v)error(e),和 complete()這些方法組成的對(duì)象。調(diào)用next(theValue)方法后,Subject會(huì)向所有已經(jīng)在其上注冊(cè)的Observer多路推送theValue。

下面的例子中,我們?cè)赟ubject上注冊(cè)了兩個(gè)Observer,并且多路推送了一些數(shù)值:

var subject = new Rx.Subject();

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

subject.next(1);
subject.next(2);

控制臺(tái)輸出結(jié)果如下:

observerA: 1
observerB: 1
observerA: 2
observerB: 2

既然Subject是一個(gè)Observer,你可以把它作為subscribe(訂閱)普通Observable時(shí)的參數(shù),如下面例子所示:

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來(lái)訂閱observable

執(zhí)行后結(jié)果如下:

observerA: 1
observerB: 1
observerA: 2
observerB: 2
observerA: 3
observerB: 3

通過(guò)上面的實(shí)現(xiàn):我們發(fā)現(xiàn)可以通過(guò)Subject將普通的Observable單路推送轉(zhuǎn)換為多路推送。這說(shuō)明了Subject的作用——作為單路Observable轉(zhuǎn)變?yōu)槎嗦稯bservable的橋梁。

還有幾種特殊的Subject 類(lèi)型,分別是BehaviorSubject,ReplaySubject,和 AsyncSubject。

多路推送的Observable

在以后的語(yǔ)境中,每當(dāng)提到“多路推送的Observable”,我們特指通過(guò)Subject構(gòu)建的Observable執(zhí)行環(huán)境。否則“普通的Observable”只是一個(gè)不會(huì)共享執(zhí)行環(huán)境并且被訂閱后才生效的一系列值。

通過(guò)使用Subject可以創(chuàng)建擁有相同執(zhí)行環(huán)境的多路的Observable。

下面展示了多路的運(yùn)作方式:Subject從普通的Observable訂閱了數(shù)據(jù),然后其他Observer又訂閱了這個(gè)Subject,示例如下:

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

// 通過(guò)`subject.subscribe({...})`訂閱Subject的Observer:
multicasted.subscribe({
  next: (v) => console.log("observerA: " + v)
});
multicasted.subscribe({
  next: (v) => console.log("observerB: " + v)
});

// 讓Subject從數(shù)據(jù)源訂閱開(kāi)始生效:
multicasted.connect();

multicast方法返回一個(gè)類(lèi)似于Observable的可觀察對(duì)象,但是在其被訂閱后,它會(huì)表現(xiàn)Subject的特性。 multicast 返回的對(duì)象同時(shí)是ConnectableObservable類(lèi)型的,擁有connect() 方法。

connect()方法非常的重要,它決定Observable何時(shí)開(kāi)始執(zhí)行。由于調(diào)用connect()后,Observable開(kāi)始執(zhí)行,因此,connect()會(huì)返回一個(gè)Subscription供調(diào)用者來(lái)終止執(zhí)行。

引用計(jì)數(shù)

通過(guò)手動(dòng)調(diào)用connect()返回的Subscription控制執(zhí)行十分繁雜。通常,我們希望在有第一個(gè)Observer訂閱Subject后自動(dòng)connnect,當(dāng)所有Observer都取消訂閱后終止這個(gè)Subject。

我們來(lái)分析一下下面例子中subscription的過(guò)程:

第一個(gè)Observer 訂閱了多路推送的 Observable

多路Observable被連接

向第一個(gè)Observer發(fā)送 值為0next通知

第二個(gè)Observer訂閱了多路推送的 Observable

向第一個(gè)Observer發(fā)送 值為1next通知

向第二個(gè)Observer發(fā)送 值為1next通知

第一個(gè)Observer取消了對(duì)多路推送的Observable的訂閱

向第二個(gè)Observer發(fā)送 值為2next通知

第二個(gè)Observer取消了對(duì)多路推送的Observable的訂閱

取消對(duì)多路推送的Observable的連接

通過(guò)顯式地調(diào)用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)
});
subscriptionConnect = multicasted.connect();

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

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

setTimeout(() => {
  subscription2.unsubscribe();
  subscriptionConnect.unsubscribe(); 
}, 2000);

如果你不想顯式地調(diào)用connect()方法,可以在ConnectableObservable類(lèi)型的Observable上調(diào)用refCount()方法。方法會(huì)進(jìn)行引用計(jì)數(shù):記錄Observable被訂閱的行為。當(dāng)訂閱數(shù)從 01時(shí)refCount() 會(huì)調(diào)用connect() 方法。到訂閱數(shù)從10,他會(huì)終止整個(gè)執(zhí)行過(guò)程。

refCount 使得多路推送的Observable在被訂閱后自動(dòng)執(zhí)行,在所有觀察者取消訂閱后,停止執(zhí)行。

下面是示例:

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

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);

setTimeout(() => {
  console.log("observerB unsubscribed");
  subscription2.unsubscribe();
}, 2000);

執(zhí)行輸出結(jié)果如下:

observerA subscribed
observerA: 0
observerB subscribed
observerA: 1
observerB: 1
observerA unsubscribed
observerB: 2
observerB unsubscribed

只有ConnectableObservables擁有refCount()方法,調(diào)用后會(huì)返回一個(gè)Observable而不是新的ConnectableObservable。

BehaviorSubject

BehaviorSubject是Subject的一個(gè)衍生類(lèi),具有“最新的值”的概念。它總是保存最近向數(shù)據(jù)消費(fèi)者發(fā)送的值,當(dāng)一個(gè)Observer訂閱后,它會(huì)即刻從BehaviorSubject收到“最新的值”。

BehaviorSubjects非常適于表示“隨時(shí)間推移的值”。舉一個(gè)形象的例子,Subject表示一個(gè)人的生日,而B(niǎo)ehavior則表示一個(gè)人的歲數(shù)。(生日只是一天,一個(gè)人的歲數(shù)會(huì)保持到下一次生日之前。)

下面例子中,展示了如何用 0初始化BehaviorSubject,當(dāng)Observer訂閱它時(shí),0是第一個(gè)被推送的值。緊接著,在第二個(gè)Observer訂閱BehaviorSubject之前,它推送了2,雖然訂閱在推送2之后,但是第二個(gè)Observer仍然能接受到2

var subject = new Rx.BehaviorSubject(0 /* 初始值 */);

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

subject.next(1);
subject.next(2);

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

subject.next(3);

輸出結(jié)果如下:

observerA: 0
observerA: 1
observerA: 2
observerB: 2
observerA: 3
observerB: 3
ReplaySubject

ReplaySubject 如同于BehaviorSubjectSubject 的子類(lèi)。通過(guò) ReplaySubject可以向新的訂閱者推送舊數(shù)值,就像一個(gè)錄像機(jī)ReplaySubject可以記錄Observable的一部分狀態(tài)(過(guò)去時(shí)間內(nèi)推送的值)。

.一個(gè)ReplaySubject可以記錄Observable執(zhí)行過(guò)程中推送的多個(gè)值,并向新的訂閱者回放它們。

你可以指定回放值的數(shù)量:

var subject = new Rx.ReplaySubject(3 /* 回放數(shù)量 */);

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

subject.next(1);
subject.next(2);
subject.next(3);
subject.next(4);

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

subject.next(5);

輸出如下:

observerA: 1
observerA: 2
observerA: 3
observerA: 4
observerB: 2
observerB: 3
observerB: 4
observerA: 5
observerB: 5

除了回放數(shù)量,你也可以以毫秒為單位去指定“窗口時(shí)間”,決定ReplaySubject記錄多久以前Observable推送的數(shù)值。下面的例子中,我們把回放數(shù)量設(shè)置為100,把窗口時(shí)間設(shè)置為500毫秒:

var subject = new Rx.ReplaySubject(100, 500 /* windowTime */);

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

var i = 1;
setInterval(() => subject.next(i++), 200);

setTimeout(() => {
  subject.subscribe({
    next: (v) => console.log("observerB: " + v)
  });
}, 1000);

第二個(gè)Observer接受到3(600ms), 4(800ms) 和 5(1000ms),這些值均在訂閱之前的500毫秒內(nèi)推送(窗口長(zhǎng)度 1000ms - 600ms = 400ms < 500ms):

observerA: 1
observerA: 2
observerA: 3
observerA: 4
observerA: 5
observerB: 3
observerB: 4
observerB: 5
observerA: 6
observerB: 6
...
AsyncSubject

AsyncSubject是Subject的另外一個(gè)衍生類(lèi),Observable僅會(huì)在執(zhí)行完成后,推送執(zhí)行環(huán)境中的最后一個(gè)值。

var subject = new Rx.AsyncSubject();

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

subject.next(1);
subject.next(2);
subject.next(3);
subject.next(4);

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

subject.next(5);
subject.complete();

輸出結(jié)果如下:

observerA: 5
observerB: 5

AsyncSubject 與 last() 操作符相似,等待完成通知后推送執(zhí)行過(guò)程的最后一個(gè)值。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/79377.html

相關(guān)文章

  • RxJS和react開(kāi)發(fā)mac地址輸入框

    摘要:項(xiàng)目簡(jiǎn)介本次使用了和開(kāi)發(fā)了一個(gè)地址輸入框,主要實(shí)現(xiàn)的功能有限制輸入符合條件的字符并每隔兩位可以自動(dòng)添加用于分割的冒號(hào)。項(xiàng)目屏蔽了的事件處理,同時(shí)使用來(lái)手動(dòng)控制光標(biāo)。繼承于和因此同時(shí)具有和兩者的方法。后面的和都是需要利用最新的來(lái)進(jìn)行判斷的。 項(xiàng)目簡(jiǎn)介 本次使用了RxJS和react開(kāi)發(fā)了一個(gè)mac地址輸入框,主要實(shí)現(xiàn)的功能有限制輸入符合條件的字符1-9,a-f,并每隔兩位可以自動(dòng)添加用于...

    CastlePeaK 評(píng)論0 收藏0
  • 從觀察者模式到迭代器模式系統(tǒng)講解 RxJS Observable(一)

    摘要:是的縮寫(xiě),起源于,是一個(gè)基于可觀測(cè)數(shù)據(jù)流結(jié)合觀察者模式和迭代器模式的一種異步編程的應(yīng)用庫(kù)。是基于觀察者模式和迭代器模式以函數(shù)式編程思維來(lái)實(shí)現(xiàn)的。學(xué)習(xí)之前我們需要先了解觀察者模式和迭代器模式,還要對(duì)流的概念有所認(rèn)識(shí)。 RxJS 是 Reactive Extensions for JavaScript 的縮寫(xiě),起源于 Reactive Extensions,是一個(gè)基于可觀測(cè)數(shù)據(jù)流 Stre...

    notebin 評(píng)論0 收藏0
  • Rxjs 核心概念

    摘要:仿宋可以把想像成一個(gè)可以發(fā)射事件的庫(kù)。在中用來(lái)處理異步事件的核心概念包括代表了未來(lái)可能會(huì)產(chǎn)生的一系列的值或事件的集合回調(diào)函數(shù)的集合,它知道如何去處理上產(chǎn)生的值或者事件,當(dāng)然也包括異常。 又一年要過(guò)去了,回顧2017,rxjs始終是我在項(xiàng)目里使用最頻繁的庫(kù),在我看來(lái),它是一個(gè)非常優(yōu)秀的數(shù)據(jù)處理工具。年初的時(shí)候就計(jì)劃寫(xiě)點(diǎn)什么,礙于目前公司的項(xiàng)目實(shí)在抽不出時(shí)間,這一拖就到了年底。臨近新年,總...

    Youngdze 評(píng)論0 收藏0
  • 通俗的方式理解RxJS

    摘要:到底是什么先上代碼輸出這里可以把想象成一個(gè)函數(shù),這意味著你每次調(diào)用都會(huì)導(dǎo)致傳入里的回調(diào)函數(shù)重新執(zhí)行一次調(diào)用的方式為相當(dāng)于。接收函數(shù)返回值的方式也從改為通過(guò)傳入回調(diào)函數(shù)的方式獲取。具體看代碼運(yùn)行結(jié)果如上的第一個(gè)回調(diào)函數(shù)里的結(jié)構(gòu)是推薦的結(jié)構(gòu)。 通俗的方式理解Rx.js 序言 今早看民工叔的文章的時(shí)候, 發(fā)現(xiàn)對(duì)Rxjs所知甚少, 于是去官方看了下教程, 整理出一些東西, 寫(xiě)成此文。Rxjs據(jù)...

    jzzlee 評(píng)論0 收藏0
  • RxJS融入React項(xiàng)目

    摘要:技術(shù)積累經(jīng)過(guò)社區(qū)的努力學(xué)習(xí)資料還是很多的,官方中文文檔就已經(jīng)很不錯(cuò),不過(guò)我們先從天精通初步感受一下然后配合一些中文文檔來(lái)補(bǔ)充知識(shí)點(diǎn),最后再根據(jù)官方文檔來(lái)校驗(yàn)整個(gè)知識(shí)體系。資料學(xué)習(xí)操作符的時(shí)候可以對(duì)照彈珠圖的交互彈珠圖的中文版中文文檔 前言 最近準(zhǔn)備畢設(shè),技術(shù)選型的時(shí)候因?yàn)楣δ艿囊恍┬枨鬁?zhǔn)備將RxJs融入到項(xiàng)目中,考慮RxJs的時(shí)候因?yàn)橹暗募夹g(shù)棧還猶豫了一下,查了一些資料以及粗略瀏覽了...

    frontoldman 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

weij

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<