理解 Observables 在 JavaScript 编程中的重要性

超甜的布丁 2021-09-17 12:17:45 浏览数 (2647)
反馈

The emitter Observable and the modulus Observable could be explicitly typed as follows: ​Reactive Extensions for JavaScript ​库是专门用于事件处理的最强大和流行的 JavaScript 库之一 ,或简称为 ​RxJS ​。 ​RxJS ​使用名为​ Observable​ 模式的四人组 ( GoF ) 设计模式作为注册事件兴趣的基础,以及在事件触发时执行某些操作。 下面,我们就一起来探索 ​RxJS ​库的基础知识以及它提供的 ​Observables​ 的基本概念。

安装 RxJS 库

要开始讨论 Observables, 我们首先安装 RxJS 库,如下所示: 

npm install rxjs 

 RxJS 库已经包括由 Typescript 所需的申报文件,所以没有必要单独使用​@types​安装它们。 

要生成一个 Observable,我们可以使用 ​of​, 如下函数: 

import { of, Observable } from "rxjs";  

const emitter : Observable<number> = of(1, 2, 3, 4); 

在这里,我们首先从​rxjs​库中导入 ​of ​函数和 ​Observable​类型 。然后我们定义一个名为​emitter​的常量变量 ,它使用通用语法将其类型定义为类型​number​的 ​Observable  ​。然后我们将​of​函数的结果分配给 发射器变量,这将创建一个从数字 1 到 4 的 ​Observable​。我们现在可以创建一个 ​Observer​,如下所示: 

emitter.subscribe((value: number) => { 
    console.log(`value: ${value}`) 
}); 

在这里,我们调用变量​emitter​上的​subscribe​函数。由于 ​emitter​ 变量是 ​Observable ​类型,它会自动公开 ​subscribe ​函数以注册​Observers​。subscribe 函数将一个函数作为参数,该函数将为 Observable 发出的每个值调用一次。这段代码的输出如下: 

value: 1 
value: 2 
value: 3 
value: 4 

在这里,我们可以看到我们传递给 subscribe 函数的函数确实为 Observable 发出的每个值调用了一次。 

请注意,只有在​Observable​上调用​subscribe ​函数时,​Observable ​才会开始发出值。调用该 ​subscribe ​函数称为订阅 ​Observable​,而 ​Observable ​产生的值也称为 ​Observable ​流。 

of​ 函数有一个名为 ​from​的伙伴函数,它使用一个数组作为 ​Observable ​的输入,如下所示: 

const emitArray : Observable<number> = from([1, 2, 3, 4]); 
 
emitArray.subscribe((value: number) => { 
    console.log(`arr: ${value}`); 
}); 

在这里,我们有一个名为​emitArray​的变量 ,它的类型是 ​Observable<number>​,并且正在使用该 ​from ​函数从数组中创建一个 ​Observable​。同样,我们对名为​emitArray​ 的 ​Observable ​上调用​subscribe​函数 ,并为 ​Observable ​发出的每个值提供一个要调用的函数。这段代码的输出如下: 

arr: 1 
arr: 2 
arr: 3 
arr: 4 

在这里,我们可以看到 ​from ​函数已经从数组输入创建了一个 ​Observable ​流,并且我们提供给 ​subscribe ​函数的函数正在为​Observable ​发出的每个值都调用一次。 

Pipe 和 Map 

RxJS 库为所有的 ​Observable ​提供了一个 ​pipe ​函数, 类似 ​subscribe ​函数。该 ​pipe函数将可变数量的函数作为参数,并将对 ​Observable ​发出的每个值执行这些函数。提供给 ​pipe ​函数的函数通常称为 ​Observable ​操作符,它们都接受一个 ​Observable ​作为输入,并返回一个 ​Observable ​作为输出。 ​pipe ​函数发出一个 ​Observable ​流。 

这个概念最好通过阅读一些代码来解释,如下例所示: 

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

在这里,我们从一个名为​emitter​的 ​Observable ​开始 ,它将发射值 1 到 4。然后我们定义一个名为​modulus ​的变量来保存对​emitter ​​Observable​​调用​pipe ​函数的结果 。我们为​pipe ​函数提供的的唯一参数是对​map ​函数的调用 ,它是 RxJS的运算符函数之一。 

map ​函数将单个函数作为参数,并将为 ​Observable ​发出的每个值调用此函数。该 ​map ​函数用于将一个值映射到另一个值,或以某种方式修改发出的值。在此示例中,我们返回将 2 的模数应用于每个值的结果。 

最后,我们订阅 ​Observable ​并将其值记录到控制台。这段代码的输出如下: 

received : 1 
modulus : 1 
received : 2 
modulus : 0 
received : 3 
modulus : 1 
received : 4 
modulus : 0 

在这里,我们可以看到 ​emitter Observable​ 发出 1 到 4 的值,并且 ​​modules Observable​​正在为接收到的每个值发出的​Modules ​2。  

请注意,在这些代码示例中,我们没有明确设置 ​Observable ​的类型。 

emitter Observable​和​​modules Observable​​可以显式类型如下: 

const emitter : Observable<number> = of(1, 2, 3, 4); 
 
const modulus : Observable<number> = emitter.pipe(  
    ... 
); 

在这里,我们指定了 ​emitter Observable​ 和​​modules Observable ​​的类型。这不是绝对必要的,因为 TypeScript 编译器会在使用 ​Observables ​时确定正确的返回类型。然而,它确实明确说明了我们对 ​Observable ​流的期望,并且在更大或更复杂的 ​Observable ​转换中,明确设置预期的返回类型使代码更具可读性并可以防止错误。 

组合运算符 

 ​pipe ​函数允许我们组合多个运算符函数,每个函数都将应用于 ​Observable ​发出的值。考虑以下代码: 

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

在这里,我们有一个​Observable​的命名 ​emitter​ ,它将发射值 1 到 4。然后我们有一个名为​stringMap​的变量  ,用于保存 ​emitter Observable​的​pipe ​函数的结果 。在这个 ​pipe ​函数中,我们有两个 ​map ​函数。第一个 ​map ​函数将传入的数值乘以 2,第二个 ​map ​函数将其转换为带有前缀的字符串 str_。 

然后我们订阅 Observable 并将每个值记录到控制台。这段代码的输出如下: 

stringMap emitted : str_2 
stringMap emitted : str_4 
stringMap emitted : str_6 
stringMap emitted : str_8 

在这里,我们可以看到两个 ​map ​函数都应用于​emitter Observable​发出的每个值 。请注意 ,在我们的第二个 ​map ​函数中,我们实际上已经将每个值的类型从 ​number ​类型修改为 ​string ​类型。 这就是为什么在我们的函数中为​value ​参数指定 ​subscribe​的类型是 ​string​ 类型的原因。 

概括 

在本篇文章中,我们已经探讨了基本的RxJS 库,它提供了可观测量的基本概念。我们已经看到了如何使用 of 和 from 函数轻松创建 Observable  。


0 人点赞