搜索
首页web前端js教程浅析Angular中的可观察对象、观察者和RxJS操作符

本篇文章带大家了解Angular中的可观察对象(Observable)、观察者(observer)和RxJS操作符,希望对大家有所帮助!

浅析Angular中的可观察对象、观察者和RxJS操作符

Observable(可观察对象)

Observable(可观察对象),是RxJS库里面的一个对象,可以用来处理异步事件,例如HTTP请求(实际上,在Angular中,所有的HTTP请求返回的都是Observable)。【相关教程推荐:《angular教程》】

或许,你以前接触过一个叫promise的东西,它们本质上面是相同的:都是生产者主动向消费者“push”产品,而消费者是被动接收的,但是他们两者还是有很大区别的:Observable可以发送任意多值,并且,在被订阅之前,它是不会执行的!这是promise不具备的特点。

  • Observable用于在发送方和接收方之间传输消息,你可以将这些消息看成是流
  • 在创建Observable对象时,需要传入一个函数作为构造函数的参数,这个函数叫订阅者函数,这个函数也就是生产者向消费者推送消息的地方
  • 在被消费者subscribe(订阅)之前,订阅者函数不会被执行,直到subscribe()函数被调用,该函数返回一个subscription对象,里面有一个unsubscribe()函数,消费者可以随时拒绝消息的接收!
  • subscribe()函数接收一个observer(观察者)对象作为入参
  • 消息的发送可以是同步的,也可以是异步的

observer(观察者)

有了可观察对象(发送方),就需要一个观察者(接收方)来观察可观察对象,观察者要实现observer接口,它是一个对象,其中包含三个属性,它们都是函数,如下:

通知类型 说明
next 必要。以接收的值作为入参,在正常情况下执行。可能执行零次或多次。
error 可选。出错的情况下执行。错误会中断这个可观察对象实例的执行过程。
complete 可选。传输完成的情况下执行。

订阅

只有当有人订阅 Observable 的实例时,它才会开始发布值。 订阅时要先调用可观察对象的 subscribe() 方法,并把一个观察者对象传给它,用来接收通知。如下:

为了展示订阅的原理,需要先创建新的可观察对象。它有一个构造函数可以用来创建新实例,但是为了更简明,也可以使用 Observable 上定义的一些静态方法来创建一些常用的简单可观察对象:

  • of(...items) :返回一个 Observable 实例,它用同步的方式把参数中提供的这些值一个一个发送出来。
  • from(iterable) : 把它的参数转换成一个 Observable 实例。 该方法通常用于把一个数组转换成一个(发送多个值的)可观察对象。
import { of } from "rxjs";
// 1、通过 of() 方法返回一个可观察对象,并准备将1,2,3三个数据发送出去
const observable = of(1, 2, 3);	
// 2、实现 observer 接口,观察者
const observer = {	
	next: (num: number) => console.log(num),
	error: (err: Error) => console.error('Observer got an error: ' + err),
  	complete: () => console.log('Observer got a complete notification'), 
}
// 3、订阅。调用可观察对象的 subscribe() 方法订阅,subscribe() 方法中传入的对象就是一个观察者
observable.subscribe(observer);

运行结果如下:


上面订阅的写法可以直接改为如下:参数不是对象

observable.subscribe(
  num => console.log(num),
  err => console.error('Observer got an error: ' + err),
  () => console.log('Observer got a complete notification')
);

订阅者函数

在上面的例子中使用的是of()方法来创建可观察对象,这节使用构造函数创建可观察对象。

Observable 构造函数可以创建任何类型的可观察流。 当执行可观察对象的 subscribe() 方法时,这个构造函数就会把它接收到的参数作为订阅函数来运行。 订阅函数会接收一个 Observer 对象,并把值发布给观察者的 next()方法。

// 1、自定义订阅者函数
function sequenceSubscriber(observer: Observer<number>) {
  observer.next(1);	// 发送数据
  observer.next(2);	// 发送数据
  observer.next(3);	// 发送数据
  observer.complete();
  return {unsubscribe() {}};
}

// 2、通过构造函数创建一个新的可观察对象,参数就是一个订阅者函数
const sequence = new Observable(sequenceSubscriber);

// 3、订阅
sequence.subscribe({
  next(num) { console.log(num); },	// 接受数据
  complete() { console.log(&#39;Finished sequence&#39;); }
});

运行结果如下:

在这里插入图片描述

上面一个例子演示了如何自定义订阅函数,那么既然可以自定义订阅者函数,我们就可以将异步代码封装进可观察对象的订阅者函数中,待异步代码执行完再发送数据。如下:

import { Observable } from &#39;rxjs&#39;
// 异步函数
function fn(num) {
    return new Promise((reslove, reject) => {
        setTimeout(() => {
            num++
            reslove(num)
        }, 1000)
    })
}
// 创建可观察对象,并传入订阅者函数
const observable = new Observable((x) => {
    let num = 1
    fn(num).then(
    	res => x.next(res)	// 异步代码执行完成,发送数据
    ) 
})
// 订阅,接收数据,可以改为链式调用
observable.subscribe(data => console.log(data))	// 2

多播

https://angular.cn/guide/observables#multicasting

RxJS操作符

我们可以使用一系列的RxJS操作符,在这些消息被接收方接收之前,对它们进行一系列的处理、转换,因为这些操作符都是纯函数。

import { of } from &#39;rxjs&#39;;
import { map } from &#39;rxjs/operators&#39;;
// 1、创建可观察对象,并发送数据
const nums = of(1, 2, 3);
// 2、创建函数以接受可观察对象
const squareValues = map((val: number) => val * val);
const squaredNums = squareValues(nums);

squaredNums.subscribe(x => console.log(x));

上面的方式我看不懂且难以接受,一般常用下面这种,使用pipe把多个操作符链接起来

import { map, Observable, filter } from &#39;rxjs&#39;

// 创建可观察对象,并传入订阅者函数
const observable = new Observable((x) => {
    x.next(1)
    x.next(2)
    x.next(3)
    x.next(4)
}).pipe(
    map(value => value*100),		// 操作符
    filter(value => value == 200)	// 操作符
)
.subscribe(data => console.log(data))	// 200

错误处理

RxJS 还提供了catchError 操作符,它允许你在管道中处理已知错误。
假设你有一个可观察对象,它发起 API 请求,然后对服务器返回的响应进行映射。如果服务器返回了错误或值不存在,就会生成一个错误。如果你捕获这个错误并提供了一个默认值,流就会继续处理这些值,而不会报错。如下:

import { map, Observable, filter, catchError, of } from &#39;rxjs&#39;

const observable = new Observable((x) => {
        x.next(1)	// 发送数据 1 和 2
        x.next(2)
}).pipe(
    map(value => {
        if (value === 1) {	// 1、当发送的数据为 1 时,将其乘以 100
            return value*100
        } else {	// 2、否则抛出错误
            throw new Error(&#39;抛出错误&#39;);
        }
    }),
    // 3、此处捕获错误并处理错误,对外发送数据 0
    catchError((err) => {
        console.log(err)
        return of(0)
    })
)
.subscribe(
    data => console.log(data),
    // 4、由于上面抛出的错误被 catchError 操作符处理(重新发送数据)了,所以这里能顺利订阅到数据而不报错
    err => console.log(&#39;接受不到数据:&#39;, err)
)

最后的运行结果如下:

在这里插入图片描述

更多编程相关知识,请访问:编程视频!!

以上是浅析Angular中的可观察对象、观察者和RxJS操作符的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:csdn。如有侵权,请联系admin@php.cn删除
JavaScript在行动中:现实世界中的示例和项目JavaScript在行动中:现实世界中的示例和项目Apr 19, 2025 am 12:13 AM

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

了解JavaScript引擎:实施详细信息了解JavaScript引擎:实施详细信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python vs. JavaScript:学习曲线和易用性Python vs. JavaScript:学习曲线和易用性Apr 16, 2025 am 12:12 AM

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

Python vs. JavaScript:社区,图书馆和资源Python vs. JavaScript:社区,图书馆和资源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

从C/C到JavaScript:所有工作方式从C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript引擎:比较实施JavaScript引擎:比较实施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

超越浏览器:现实世界中的JavaScript超越浏览器:现实世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)