- RxJS官方教程(一) 概覽
- RxJS官方教程(二) Observable
- RxJS官方教程(三) Observable剖析
- RxJS官方教程(四) Observer和Subscription
- RxJS官方教程(五) Subject
- RxJS官方教程(六) 算子
Observable 可觀察對(duì)象
Observable是多個(gè)值的惰性Push集合。
單 | 多 | |
---|---|---|
拉 | Function |
Iterator |
推 | Promise |
Observable |
例 以下是一個(gè)可觀察對(duì)象洒嗤,當(dāng)被訂閱時(shí)洁奈,會(huì)立即推送1
,2
喉钢,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 拉與推
Pull和Push是兩種不同的協(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