The emitter Observable and the modulus Observable could be explicitly typed as follows: ?Reactive Extensions for JavaScript ?庫(kù)是專門用于事件處理的最強(qiáng)大和流行的 JavaScript 庫(kù)之一 ,或簡(jiǎn)稱為 ?RxJS ?。 ?RxJS ?使用名為? Observable? 模式的四人組 ( GoF ) 設(shè)計(jì)模式作為注冊(cè)事件興趣的基礎(chǔ),以及在事件觸發(fā)時(shí)執(zhí)行某些操作。 下面,我們就一起來探索 ?RxJS ?庫(kù)的基礎(chǔ)知識(shí)以及它提供的 ?Observables? 的基本概念。
安裝 RxJS 庫(kù)
要開始討論 Observables, 我們首先安裝 RxJS 庫(kù),如下所示:
npm install rxjs
RxJS 庫(kù)已經(jīng)包括由 Typescript 所需的申報(bào)文件,所以沒有必要單獨(dú)使用?@types
?安裝它們。
要生成一個(gè) Observable,我們可以使用 ?of
?, 如下函數(shù):
import { of, Observable } from "rxjs";
const emitter : Observable<number> = of(1, 2, 3, 4);
在這里,我們首先從?rxjs
?庫(kù)中導(dǎo)入 ?of
?函數(shù)和 ?Observable
?類型 。然后我們定義一個(gè)名為?emitter
?的常量變量 ,它使用通用語(yǔ)法將其類型定義為類型?number
?的 ?Observable
?。然后我們將?of
?函數(shù)的結(jié)果分配給 發(fā)射器變量,這將創(chuàng)建一個(gè)從數(shù)字 1 到 4 的 ?Observable
?。我們現(xiàn)在可以創(chuàng)建一個(gè) ?Observer
?,如下所示:
emitter.subscribe((value: number) => {
console.log(`value: ${value}`)
});
在這里,我們調(diào)用變量?emitter
?上的?subscribe
?函數(shù)。由于 ?emitter
? 變量是 ?Observable
?類型,它會(huì)自動(dòng)公開 ?subscribe
?函數(shù)以注冊(cè)?Observers
?。subscribe 函數(shù)將一個(gè)函數(shù)作為參數(shù),該函數(shù)將為 Observable 發(fā)出的每個(gè)值調(diào)用一次。這段代碼的輸出如下:
value: 1
value: 2
value: 3
value: 4
在這里,我們可以看到我們傳遞給 subscribe 函數(shù)的函數(shù)確實(shí)為 Observable 發(fā)出的每個(gè)值調(diào)用了一次。
請(qǐng)注意,只有在?Observable
?上調(diào)用?subscribe
?函數(shù)時(shí),?Observable
?才會(huì)開始發(fā)出值。調(diào)用該 ?subscribe
?函數(shù)稱為訂閱 ?Observable
?,而 ?Observable
?產(chǎn)生的值也稱為 ?Observable
?流。
?of
? 函數(shù)有一個(gè)名為 ?from
?的伙伴函數(shù),它使用一個(gè)數(shù)組作為 ?Observable
?的輸入,如下所示:
const emitArray : Observable<number> = from([1, 2, 3, 4]);
emitArray.subscribe((value: number) => {
console.log(`arr: ${value}`);
});
在這里,我們有一個(gè)名為?emitArray
?的變量 ,它的類型是 ?Observable<number>
?,并且正在使用該 ?from
?函數(shù)從數(shù)組中創(chuàng)建一個(gè) ?Observable
?。同樣,我們對(duì)名為?emitArray
? 的 ?Observable
?上調(diào)用?subscribe
?函數(shù) ,并為 ?Observable
?發(fā)出的每個(gè)值提供一個(gè)要調(diào)用的函數(shù)。這段代碼的輸出如下:
arr: 1
arr: 2
arr: 3
arr: 4
在這里,我們可以看到 ?from
?函數(shù)已經(jīng)從數(shù)組輸入創(chuàng)建了一個(gè) ?Observable
?流,并且我們提供給 ?subscribe
?函數(shù)的函數(shù)正在為?Observable
?發(fā)出的每個(gè)值都調(diào)用一次。
Pipe 和 Map
RxJS 庫(kù)為所有的 ?Observable
?提供了一個(gè) ?pipe
?函數(shù), 類似 ?subscribe
?函數(shù)。該 ?pipe
函數(shù)將可變數(shù)量的函數(shù)作為參數(shù),并將對(duì) ?Observable
?發(fā)出的每個(gè)值執(zhí)行這些函數(shù)。提供給 ?pipe
?函數(shù)的函數(shù)通常稱為 ?Observable
?操作符,它們都接受一個(gè) ?Observable
?作為輸入,并返回一個(gè) ?Observable
?作為輸出。 ?pipe
?函數(shù)發(fā)出一個(gè) ?Observable
?流。
這個(gè)概念最好通過閱讀一些代碼來解釋,如下例所示:
import { map } from "rxjs/operators";
const emitter = of(1, 2, 3, 4);
const modulus = emitter.pipe(
map((value: number) => {
console.log(`received : ${value}`);
return value % 2;
}));
modulus.subscribe((value: number) => {
console.log(`modulus : ${value}`);
});
在這里,我們從一個(gè)名為?emitter
?的 ?Observable
?開始 ,它將發(fā)射值 1 到 4。然后我們定義一個(gè)名為?modulus
?的變量來保存對(duì)?emitter
???Observable
??調(diào)用?pipe
?函數(shù)的結(jié)果 。我們?yōu)?pipe
?函數(shù)提供的的唯一參數(shù)是對(duì)?map
?函數(shù)的調(diào)用 ,它是 RxJS的運(yùn)算符函數(shù)之一。
?map
?函數(shù)將單個(gè)函數(shù)作為參數(shù),并將為 ?Observable
?發(fā)出的每個(gè)值調(diào)用此函數(shù)。該 ?map
?函數(shù)用于將一個(gè)值映射到另一個(gè)值,或以某種方式修改發(fā)出的值。在此示例中,我們返回將 2 的模數(shù)應(yīng)用于每個(gè)值的結(jié)果。
最后,我們訂閱 ?Observable
?并將其值記錄到控制臺(tái)。這段代碼的輸出如下:
received : 1
modulus : 1
received : 2
modulus : 0
received : 3
modulus : 1
received : 4
modulus : 0
在這里,我們可以看到 ?emitter Observable
? 發(fā)出 1 到 4 的值,并且 ??modules Observable
??正在為接收到的每個(gè)值發(fā)出的?Modules
?2。
請(qǐng)注意,在這些代碼示例中,我們沒有明確設(shè)置 ?Observable
?的類型。
?emitter Observable
?和??modules Observable
??可以顯式類型如下:
const emitter : Observable<number> = of(1, 2, 3, 4);
const modulus : Observable<number> = emitter.pipe(
...
);
在這里,我們指定了 ?emitter Observable
? 和??modules Observable
??的類型。這不是絕對(duì)必要的,因?yàn)?TypeScript 編譯器會(huì)在使用 ?Observables
?時(shí)確定正確的返回類型。然而,它確實(shí)明確說明了我們對(duì) ?Observable
?流的期望,并且在更大或更復(fù)雜的 ?Observable
?轉(zhuǎn)換中,明確設(shè)置預(yù)期的返回類型使代碼更具可讀性并可以防止錯(cuò)誤。
組合運(yùn)算符
?pipe
?函數(shù)允許我們組合多個(gè)運(yùn)算符函數(shù),每個(gè)函數(shù)都將應(yīng)用于 ?Observable
?發(fā)出的值。考慮以下代碼:
const emitter = of(1, 2, 3, 4);
const stringMap = emitter.pipe(
map((value: number) => { return value * 2 }),
map((value: number) => { return `str_${value}` })
);
stringMap.subscribe((value: string) => {
console.log(`stringMap emitted : ${value}`);
});
在這里,我們有一個(gè)?Observable
?的命名 ?emitter
? ,它將發(fā)射值 1 到 4。然后我們有一個(gè)名為?stringMap
?的變量 ,用于保存 ?emitter Observable
?的?pipe
?函數(shù)的結(jié)果 。在這個(gè) ?pipe
?函數(shù)中,我們有兩個(gè) ?map
?函數(shù)。第一個(gè) ?map
?函數(shù)將傳入的數(shù)值乘以 2,第二個(gè) ?map
?函數(shù)將其轉(zhuǎn)換為帶有前綴的字符串 str_。
然后我們訂閱 Observable 并將每個(gè)值記錄到控制臺(tái)。這段代碼的輸出如下:
stringMap emitted : str_2
stringMap emitted : str_4
stringMap emitted : str_6
stringMap emitted : str_8
在這里,我們可以看到兩個(gè) ?map
?函數(shù)都應(yīng)用于?emitter Observable
?發(fā)出的每個(gè)值 。請(qǐng)注意 ,在我們的第二個(gè) ?map
?函數(shù)中,我們實(shí)際上已經(jīng)將每個(gè)值的類型從 ?number
?類型修改為 ?string
?類型。 這就是為什么在我們的函數(shù)中為?value
?參數(shù)指定 ?subscribe
?的類型是 ?string
? 類型的原因。
概括
在本篇文章中,我們已經(jīng)探討了基本的RxJS 庫(kù),它提供了可觀測(cè)量的基本概念。我們已經(jīng)看到了如何使用 of 和 from 函數(shù)輕松創(chuàng)建 Observable 。