RxJS官方教程(二) Observable

Observable 可觀察對(duì)象

Observable是多個(gè)值的惰性Push集合。

Function Iterator
Promise Observable

以下是一個(gè)可觀察對(duì)象洒嗤,當(dāng)被訂閱時(shí)洁奈,會(huì)立即推送12喉钢,3税课,并且4在一秒之后推送,然后完成:

var observable = Rx.Observable.create(function (observer) {
    observer.next(1);
    observer.next(2);
    observer.next(3);
    setTimeout(() => {
       observer.next(4);
       observer.complete();
    }, 1000);
});

要調(diào)用Observable并查看這些值佛析,我們需要訂閱它:

var observable = Rx.Observable.create(function (observer) {
    observer.next(1);
    observer.next(2);
    observer.next(3);
    setTimeout(() => {
       observer.next(4);
       observer.complete();
    }, 1000);
});

console.log('just before subscribe');
observable.subscribe({
    next: x => console.log('got value ' + x),
    error: err => console.error('something wrong occurred: ' + err),
    complete: () => console.log('done'),
});
console.log('just after subscribe');

這在控制臺(tái)上執(zhí)行如下:

just before subscribe
got value 1
got value 2
got value 3
just after subscribe
got value 4
done

Pull & Push 拉與推

PullPush是兩種不同的協(xié)議辽狈,描述了數(shù)據(jù)生產(chǎn)者如何與數(shù)據(jù)消費(fèi)者進(jìn)行通信。

什么是Pull?在Pull系統(tǒng)中伟阔,消費(fèi)者會(huì)確定何時(shí)從數(shù)據(jù)生產(chǎn)者接收數(shù)據(jù)合搅。生產(chǎn)者本身并不知道何時(shí)將數(shù)據(jù)傳遞給消費(fèi)者。

每個(gè)JavaScript函數(shù)都是一個(gè)Pull系統(tǒng)扫责。該函數(shù)是數(shù)據(jù)的生產(chǎn)者,調(diào)用該函數(shù)的代碼通過(guò)從其調(diào)用中“拉出” 單個(gè)返回值來(lái)消耗它。

另一種類型的Pull系統(tǒng)是ES2015引入的生成器函數(shù)和迭代器function*)藏古。調(diào)用的代碼iterator.next()是Consumer,從迭代器(Producer)“拉出” 多個(gè)值。

制片人 消費(fèi)者
被動(dòng):在請(qǐng)求時(shí)生成數(shù)據(jù)奈嘿。 活動(dòng):決定何時(shí)請(qǐng)求數(shù)據(jù)践图。
活動(dòng):按照自己的節(jié)奏生成數(shù)據(jù)憾股。 被動(dòng):對(duì)收到的數(shù)據(jù)做出反應(yīng)婉商。

什么是推?在Push系統(tǒng)中渣叛,生產(chǎn)者確定何時(shí)向消費(fèi)者發(fā)送數(shù)據(jù)丈秩。消費(fèi)者不知道何時(shí)會(huì)收到該數(shù)據(jù)。

Promise是當(dāng)今JavaScript中最常見(jiàn)的Push系統(tǒng)類型淳衙。Promise(生產(chǎn)者)為已注冊(cè)的回調(diào)(消費(fèi)者)提供已解決的值蘑秽,但與功能不同,Promise負(fù)責(zé)確定何時(shí)將該值“推送”到回調(diào)箫攀。

RxJS引入了Observable肠牲,一種新的JavaScript推送系統(tǒng)。Observable是多個(gè)值的生產(chǎn)者靴跛,將它們“推送”給Observer(消費(fèi)者)缀雳。

  • Function 惰性計(jì)算,同步返回單個(gè)值梢睛。
  • generator 惰性計(jì)算肥印,按迭代計(jì)算,同步返回零至(潛在地)無(wú)窮多的值绝葡。
  • **Promise **可能(也可能不會(huì))返回一個(gè)值深碱。
  • Observable 惰性計(jì)算,并可以同步或異步返回零至(潛在的)無(wú)窮多的值藏畅。

Observable概括

與流行的說(shuō)法相反敷硅,Observables不像EventEmitters,也不像Promises的多值。當(dāng)使用RxJS Subjects進(jìn)行多播時(shí)绞蹦,Observable 行為有點(diǎn)像EventEmitters力奋,其他情況下和EventEmitters表現(xiàn)不一樣。

Observable類似于零參數(shù)的函數(shù)幽七,但是將它們概括為允許多個(gè)值景殷。

考慮以下:

function foo(){
    console.log('hello');
    return 42;
}

var x = foo.call(); // same as foo()
console.log(x);
var y = foo.call(); // same as foo()
console.log(y);

我們希望看到輸出:

"Hello"
42
"Hello"
42

您可以使用Observables編寫(xiě)相同的行為:

var foo = Rx.Observable.create(function (observer) {
  console.log('Hello');
  observer.next(42);
});

foo.subscribe(function (x) {
  console.log(x);
});
foo.subscribe(function (y) {
  console.log(y);
});

輸出是一樣的:

"Hello"
42
"Hello"
42

發(fā)生這種情況是因?yàn)楹瘮?shù)和Observable都是惰性計(jì)算。如果你不調(diào)用該函數(shù)锉走,console.log('Hello')則不會(huì)發(fā)生滨彻。對(duì)于Observables,如果你沒(méi)有“調(diào)用”它(with subscribe)挪蹭,那么console.log('Hello')就不會(huì)發(fā)生亭饵。另外,“調(diào)用”或“訂閱”是一個(gè)獨(dú)立的操作:兩個(gè)函數(shù)調(diào)用觸發(fā)兩個(gè)單獨(dú)的副作用梁厉,兩個(gè)Observable訂閱觸發(fā)兩個(gè)單獨(dú)的副作用辜羊。與無(wú)論訂閱者是否存在共享副作用并且急切執(zhí)行的EventEmitters相反,Observables沒(méi)有共享執(zhí)行并且是懶惰的词顾。

訂閱Observable類似于調(diào)用函數(shù)八秃。

有些人聲稱Observables是異步的。事實(shí)并非如此肉盹。如果您使用日志包圍函數(shù)調(diào)用昔驱,如下所示:

console.log('before');
console.log(foo.call());
console.log('after');

你會(huì)看到輸出:

"before"
"Hello"
42
"after"

這與Observables的行為相同:

console.log('before');
foo.subscribe(function (x) {
  console.log(x);
});
console.log('after');

輸出是:

"before"
"Hello"
42
"after"

這證明訂閱foo是完全同步的,就像一個(gè)函數(shù)上忍。

Observable能夠同步或異步傳遞值骤肛。

Observable和函數(shù)之間有什么區(qū)別?Observable可以隨時(shí)間“返回”多個(gè)值窍蓝,而函數(shù)則不能腋颠。你不能這樣做:

function foo() {
  console.log('Hello');
  return 42;
  return 100; // dead code. will never happen
}

函數(shù)只能返回一個(gè)值。但是吓笙,Observable可以這樣做:

var foo = Rx.Observable.create(function (observer) {
  console.log('Hello');
  observer.next(42);
  observer.next(100); // "return" another value
  observer.next(200); // "return" yet another
});

console.log('before');
foo.subscribe(function (x) {
  console.log(x);
});
console.log('after');

使用同步輸出:

"before"
"Hello"
42
100
200
"after"

但您也可以異步“返回”值:

var foo = Rx.Observable.create(function (observer) {
  console.log('Hello');
  observer.next(42);
  observer.next(100);
  observer.next(200);
  setTimeout(() => {
    observer.next(300); // happens asynchronously
  }, 1000);
});

console.log('before');
foo.subscribe(function (x) {
  console.log(x);
});
console.log('after');

輸出:

"before"
"Hello"
42
100
200
"after"
300

結(jié)論:

  • func.call()意思是“ 同步給我一個(gè)價(jià)值
  • observable.subscribe()意思是“ 給我任意數(shù)量的值淑玫,無(wú)論是同步還是異步

官網(wǎng) http://reactivex.io/rxjs/manual/overview.html#observable

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市面睛,隨后出現(xiàn)的幾起案子絮蒿,更是在濱河造成了極大的恐慌,老刑警劉巖侮穿,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歌径,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡亲茅,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)克锣,“玉大人茵肃,你說(shuō)我怎么就攤上這事∠睿” “怎么了验残?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)巾乳。 經(jīng)常有香客問(wèn)我您没,道長(zhǎng),這世上最難降的妖魔是什么胆绊? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任氨鹏,我火速辦了婚禮,結(jié)果婚禮上压状,老公的妹妹穿的比我還像新娘仆抵。我一直安慰自己,他們只是感情好种冬,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布镣丑。 她就那樣靜靜地躺著,像睡著了一般娱两。 火紅的嫁衣襯著肌膚如雪莺匠。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,262評(píng)論 1 308
  • 那天十兢,我揣著相機(jī)與錄音趣竣,去河邊找鬼。 笑死纪挎,一個(gè)胖子當(dāng)著我的面吹牛期贫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播异袄,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼通砍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了烤蜕?” 一聲冷哼從身側(cè)響起封孙,我...
    開(kāi)封第一講書(shū)人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎讽营,沒(méi)想到半個(gè)月后虎忌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡橱鹏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年膜蠢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了堪藐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挑围,死狀恐怖礁竞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杉辙,我是刑警寧澤模捂,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站蜘矢,受9級(jí)特大地震影響狂男,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜品腹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一岖食、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧珍昨,春花似錦县耽、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至兄春,卻和暖如春澎剥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赶舆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工哑姚, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芜茵。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓叙量,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親九串。 傳聞我的和親對(duì)象是個(gè)殘疾皇子绞佩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 推薦我的Rxjs教程:Rxjs系列教程目錄 前言 隨著開(kāi)發(fā)中項(xiàng)目的越來(lái)越大,代碼的要求越來(lái)越高猪钮,于是開(kāi)始四處搜找各...
    儂姝沁兒閱讀 10,193評(píng)論 1 6
  • 介紹 RxJS是一個(gè)異步編程的庫(kù)品山,同時(shí)它通過(guò)observable序列來(lái)實(shí)現(xiàn)基于事件的編程。它提供了一個(gè)核心的類型:...
    泓滎閱讀 16,612評(píng)論 0 12
  • 響應(yīng)式編程簡(jiǎn)介 響應(yīng)式編程是一種基于異步數(shù)據(jù)流概念的編程模式烤低。數(shù)據(jù)流就像一條河:它可以被觀測(cè)肘交,被過(guò)濾,被操作扑馁,或者...
    說(shuō)碼解字閱讀 3,074評(píng)論 0 5
  • 本篇文章介主要紹RxJava中操作符是以函數(shù)作為基本單位涯呻,與響應(yīng)式編程作為結(jié)合使用的凉驻,對(duì)什么是操作、操作符都有哪些...
    嘎啦果安卓獸閱讀 2,866評(píng)論 0 10
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理魄懂,服務(wù)發(fā)現(xiàn)沿侈,斷路器闯第,智...
    卡卡羅2017閱讀 134,701評(píng)論 18 139