发布于 2026-01-06 7 阅读
0

Angular Theory DEV 的全球展示挑战赛,由 Mux 呈现:展示你的项目!

角理论

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

为自己总结的Angular理论知识。

一些需要了解的事情

HTML DOM

HTML 文档对象模型 (
DOM)。DOM 是网页的面向对象表示,可以使用 JavaScript 等脚本语言进行修改。延伸阅读

目录

Angular 简介

npm + typescript

Angular CLI 问题

Angular架构问题

子组件(ViewChild、ViewChildren、ContentChild、ContentChildren)

Angular 生命周期问题

HTTP

传递数据

管道

RxJS

什么是角度

JavaScript 框架。
主要功能:
帮助将视图(HTML)绑定到模型(对象)。这有助于开发者实现 MVC 框架。纯 JavaScript 需要编写大量代码。
主要特性:

  1. SPA(单页应用程序)。Angular 帮助开发者实现带有路由的单页应用程序。(URL 会变化,但只有一个 index.html 文件)
  2. 依赖注入。(Angular 帮助开发者实例化组件)例如,要将服务注入组件,只需将其放入构造函数中即可。

Angular 与 AngularJS

说实话,我不太确定,我尽量避免使用AngularJS哈哈

  1. Javascript 与 Typescript
  2. CLI 构建器
  3. 可以使用 Angular CLI 构建组件和服务
  4. 懒加载
  5. 仅在需要时加载特定模块。仅当用户导航到相应模块的路由时才会加载。查看更多

Angular中的指令是什么?

用于告诉 Angular 如何转换 HTML DOM 的 HTML 指令

3项主要指令(SAC)

  1. 组件指令
  2. 结构指令
  3. 属性指令

请注意:组件在技术上是一种指令。

组件指令

使用模板的指令。它类似于用户控件。

组件从技术上讲是一种指令。@Component它扩展了@Directive

例如,声明一个自定义组件 my-grid。组件指令如下:<my-grid></my-grid>

更多信息请参阅文档。

结构指令

更改元素结构(添加/删除 DOM),
例如 NgIf、NgFor、NgSwitch(ngif 的 switch case 语句)

属性指令

更改元素的行为和外观
,例如 NgStyle、NgClass

阅读本文了解更多信息

NPM 和 node_modules 文件夹

NPM = Node.js 包管理器,
简化了 JS 框架库的安装。node_modules
= 所有包的安装目录,
它也像一个缓存。当开发者导入库时,如果没有指定路径,Node.js 会查找 node_modules 文件夹。
(摘自SitePointStack Overflow
的全局与本地部署)

package.json 文件

它列出了所有 JS 引用(即项目的依赖项、库名称)。因此,开发人员可以一次性快速安装所有依赖项npm install
可以通过以下命令从头开始重新创建 node_modules 目录。npm install

package.json 与 package-lock.json

package.json 文件记录应用程序所需库的最低版本。它还定义项目属性,例如作者等。package
-lock 文件仅用于将依赖项锁定到特定版本号。它记录每个已安装包的确切版本。

什么是 TypeScript?

Javascript 的超集。

  • 为 JavaScript 添加类型
  • 面向对象的编程环境,可编译成JS

这导致

  • 更少的错误
  • 更高的代码质量/生产力???

最终,TS 会被编译成 JS。

关于guru99的更多信息

  • 错误会在编译时指出(代码需要编译)。
  • TypeScript 使用类型和接口等概念来描述数据。
  • TS需要编译。必须编译成JS。

Angular CLI 的重要性/优势

帮助开发人员生成样板代码,而不是从头开始编写。

  • 生成现成的项目ng new my-app(生成源文件、模块文件)
  • 生成现成的原理图(例如,组件/服务/指令)ng generate service/component 文档

Angular 中组件和模块的重要性

组件是 Angular 的主要构建模块。每个组件由以下部分组成:

  1. HTML模板(声明页面上呈现的内容)
  2. 定义行为的 TypeScript 类
  3. CSS 选择器,用于定义组件在模板中的使用方式
  4. 应用于模板的 CSS 样式(来自文档)

组件与模块

成分:

  1. 控件视图(html)
  2. 与其他组件和服务通信,为应用程序带来功能

模块包括:

  1. 组件的逻辑分组

参考:SO 答案

Angular 中的装饰器(注解/元数据)是什么?

告诉 Angular 这是一个什么类型的类。 例如,
在类声明上方: -> Angular 组件。- > Angular 模块 (也可能有人会问如何在 Angular 中创建组件和模块)**
@Component@NgModule

在Angular中声明组件和模块时,必须使用装饰器。

Angular 中的模板是什么?

Angular 的 HTML 视图,您可以在其中编写指令

编写模板有两种方法:

  1. @Component({template: <<here>>})内联(在指令中定义)
  2. 单独的 HTML 文件(在组件 templateUrl 中定义)

更多信息请点击此处

Angular中的数据绑定是什么?

组件和视图如何相互通信?
文档更多详情

  1. 插值 ------{{expression}}
  2. 属性绑定-----[target]=expression
  3. 事件绑定--------(target)=statement
  4. 双向装订-----[(ngModel)]

插值

数据从组件单向流向
视图。可以用 HTML 实现(单向)。

财产

组件单向数据传输。
数据从组件流向视图集的特定元素属性。

事件绑定

单向通信,从事件/视图到组件。
视图中的事件触发组件中的函数。监听元素更改事件。

双向绑定

双向绑定,结合了属性绑定和事件绑定。

在组件中设置事件。如果视图中发生某个事件,它可以触发组件中的函数。
例如,最常用于模板表单。

更多详情请参阅文档。

要使双向绑定生效,@Output必须使用模式,inputChange其中是属性input名称, 例如@Input

export class SizerComponent {

  @Input()  size: number | string;
  @Output() sizeChange = new EventEmitter<number>();
  resize(delta: number) {
    this.size = Math.min(40, Math.max(8, +this.size + delta));
    this.sizeChange.emit(this.size);
  }
}
Enter fullscreen mode Exit fullscreen mode

使用双向装订看起来像这样:

<app-sizer [(size)]="fontSizePx"></app-sizer>
Enter fullscreen mode Exit fullscreen mode

请解释一下Angular的架构?

Angular 由 7 个主要构建模块组成:

替代文字

  1. 模板(HTML视图)
  2. 组件(绑定视图和模型)
  3. 绑定(组件和模板如何相互通信)
  4. 模块(按逻辑对组件进行分组)
  5. 指令(改变 DOM 的样式/行为)
  6. 服务(在项目间共享通用逻辑)
  7. 依赖注入(将实例注入到构造函数中)(例如,将服务注入到组件中——只需将其放入组件构造函数中)

更多说明请参见文档。

什么是SPA?

单页应用
程序(SPA)是一种通过动态地从 Web 服务器获取新数据并重写当前网页来与用户交互的 Web 应用程序/网站。
意味着主界面只需加载一次,其他功能则根据用户操作按需加载。
在生产环境中,这意味着只有一个包含 CSS 和 JavaScript 包的 index.html 文件。
这在需要丰富的客户端功能时尤为有利。由于页面完全重新加载的情况很少见,SPA 的加载速度通常更快。

例如,一个页面通常包含页眉、页脚和抽屉式导航栏。在单页应用程序 (SPA) 中,只会加载这些元素之间的部分,而不是整个页面。这样可以提高性能。

更多关于 SPA 的信息,请访问Angular 大学博客。

如何在Angular中实现单页应用程序(SPA)

路由

Angular路由是一个简单的集合,包含两部分:

  1. URL
  2. 调用 URL 时要加载的组件

它有助于定义 Angular 应用的导航。它将类似 URL 的路径映射到视图,而不是页面。因此,当用户从一个屏幕/URL 跳转到另一个屏幕/URL 时,应用会加载组件,而不是加载一个全新的页面。

Angular 中的路由是什么?

在 Angular 中,路由包含以下部分:

  1. 路径(URL路径)
  2. 成分
  3. (可选)重定向到路径

路由将 URL 路径映射到组件。
它帮助用户在应用程序中执行任务时从一个视图导航到另一个视图。
由于只有页面中的组件发生变化,而无需重新加载整个页面,因此路由有助于开发者更好地利用单页应用程序 (SPA)。

摘自:pluralsightsmashingmagazine

如何在Angular中实现路由?

  1. 在 Angular 中定义路由集合 --> 将 URL 路径映射到组件
  2. 定义路由器出口 --> 组件将显示在此处
  3. HTML 中的 [routerLink] 或 TS 文件中的 this.router.navigate(url) --> 允许用户导航到不同的路由/视图

什么是延迟加载

按需加载。
仅在需要时加载必要的 HTML、CSS 和 JS 文件。仅在需要时(例如,当用户执行特定操作时)加载其他组件。

如何实现懒加载?

  1. 将项目划分为多个独立模块
  2. loadChildren在路由对象中声明属性

Angular 中的服务是什么?

该服务帮助开发人员在组件之间共享通用逻辑/通用功能

服务与组件

根据文档,
组件的目的是为了提升用户体验,仅此而已。组件应该:提供用于数据绑定的属性和方法,以在模板(视图)和应用程序逻辑(模型
之间进行协调。

组件应将其他任务(例如从服务器获取数据、验证用户输入)委托给服务。服务中的任务也可以通过依赖注入
与其他组件共享。

什么是依赖注入?

应用设计模式: 开发者无需创建对象实例(无需实例化服务,Angular 通过构造函数注入)。
替代文字
let service: ExampleService = new ExampleService()

export class ExampleComponent{
  constructor (private service: ExampleService) {
    this.service.doSomething();
  }
}
Enter fullscreen mode Exit fullscreen mode

摘自文档

如何在Angular中实现依赖注入?

提供服务有三种方式。

  1. 根服务在根级别提供,Angular 会创建一个共享的(即单例)服务实例,并将其注入到任何请求该服务的类中。

可注射根部装饰器在服务类中提供。

@Injectable({
 providedIn: 'root',
})
Enter fullscreen mode Exit fullscreen mode

这是自动生成的,ng generate service
仅向特定模块提供服务,更改rootExampleModule

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'any',
})
export class UserService {
}
Enter fullscreen mode Exit fullscreen mode

所有providedIn: any预加载的实例共享一个单例实例,而延迟加载的模块则各自拥有一个唯一的实例。
替代文字

  1. providers在 NgModule中,在数组中提供模块注册服务
@NgModule({
  providers: [
  ExampleService,
  Logger
 ],
 ...
})
Enter fullscreen mode Exit fullscreen mode

如果 NgModule 是根 AppModule,
ExampleService它将是单例模式,并在整个应用程序中可用。
参考

AppModule 通过在AND延迟加载模块中导入服务,应用程序可以生成服务的多个实例。

  1. 在组件级别注册提供程序,每个新实例都会获得一个服务实例。
@Component({
  selector:    'app-hero-list',
  templateUrl: './hero-list.component.html',
  providers:  [ HeroService ]
})
Enter fullscreen mode Exit fullscreen mode

更多阅读资料请参阅相关文档。

依赖注入的优势

解耦类依赖关系。
可以在不修改所有组件类代码的情况下更改服务类的依赖关系。如果服务类的实例化位于组件中,则必须修改所有服务实例化代码。

也就是说,只需更改服务构造函数中的参数即可,无需更改其他任何地方。

ng serve 与 ng build

ng serve- 在内存中构建 Angular 应用程序
ng build- 在硬盘上构建应用程序。将所有编译后的代码放在/dist文件夹中

--prod 标志?

--prod该标志确保您构建的应用程序可用于生产环境。它会压缩 JS 文件,移除注释,使应用程序做好生产准备。

组件生命周期的重要性?

指令也有生命周期。

简而言之,开发者可以通过实现生命周期钩子
接口 来调用组件生命周期的关键事件并编写自定义代码。(例如:)更多详情请参阅文档。ngOnInit()

组件实例具有生命周期,从 Angular 实例化组件类并渲染组件视图,直到 Angular 销毁组件并从 DOM 中删除渲染的模板。

开发人员可以使用生命周期钩子方法来接入生命周期的关键事件,以初始化新实例/在删除实例之前进行清理。

组件生命周期中的事件和顺序?

Shivani 在 Medium 上发表了一篇很棒的文章,深入探讨了 Angular 的生命周期。

Angular 文档提供了生命周期事件序列列表

两种类型的事件

  1. 组件首次加载时触发的事件
  2. 变更检测触发事件

替代文字

生命周期事件列表
(仅发生一次的事件以斜体显示

  1. 构造函数(更像是 TypeScript 事件,而不是 Angular 事件)
  2. ngOnChanges(也称为数据绑定输入属性@Input更改时调用的事件)。此事件发生频率非常高。
  3. ngOnInit(屏幕上显示的数据绑定属性/设置组件@Input属性)
  4. ngDoCheck()(在每次变更检测运行时,ngOnChanges() 之后立即触发)
  5. ngAfterContentInit(在 Angular 将外部内容投影到组件视图之后)与<ng-check>
  6. ngAfterContentCheck(检查投影内容)
  7. ngAfterViewInit(在 Angular 初始化组件视图及其子视图之后)
  8. ngAfterViewChecked(在 Angular 检查组件的视图及其子视图之后)
  9. ngOnDestroy(Angular 销毁组件前的清理操作)

三部分

  1. 启动事件(变更检测)(ngOninit,ngDoCheck)
  2. 投影内容事件触发(ngAfterContentInit,ngAfterContentChecked)
  3. 组件视图事件触发(ngAfterViewInit、ngAfterViewChecked)

构造函数与 ngOnInit()?

  1. 构造函数 - TypeScript 概念,由 TypeScript 调用
  2. ngOnInit - Angular 概念/事件,由 Angular 框架调用

顺序:

  1. 构造函数是火。
  2. 视图和组件已初始化,绑定已完成。
  3. ngOnInit(组件初始化后,访问 DOM 元素)

构造函数:

  1. 初始化类变量
  2. 依赖注入

ngOnInit:

  1. 访问类变量
  2. 访问@Input变量

访问@Input或从构造函数访问将给出undefined

更多信息仅在该SO 答案中提供。
@ViewChildngAfterViewInit

ViewChild 和 ViewChildren

@ViewChild:引用组件中的一个
@ViewChildrenHTML 元素/DOM 元素:引用元素集合

如果检测到多个元素@ViewChild,则只会引用第一个元素。

模板引用变量

模板变量帮助开发者在模板的另一部分中使用来自模板一部分的数据。

<input #phone placeholder="phone number" />

<!-- lots of other elements -->

<!-- phone refers to the input element; pass its `value` to an event handler -->
<button (click)="callPhone(phone.value)">Call</button>
Enter fullscreen mode Exit fullscreen mode

要将模板引用变量与 ViewChild 一起使用

<div #div1> this div </div>

@Viewchild('div1',{static: false}) div: ElementRef
Enter fullscreen mode Exit fullscreen mode

更多信息请点击此处

什么是内容投射?

投影:将父组件的 HTML 内容/组件内容投影到子组件。

<ng-content></ng-content>
允许您将影子 DOM 作为输入插入到组件中。

@Input仅允许您向组件传递简单的字符串/对象。<ng-content>允许您传递 HTML 元素或其他组件。

<app-component>
  <h1>Header</h1>
  <p>paragraph</p>
</app-component>
Enter fullscreen mode Exit fullscreen mode

多内容投影:内容投影槽
GreetComponent

<div class="container">
  <ng-content> </ng-content>
  <ng-content select="h1"></ng-content>
  <p>welcome text</p>
  <ng-content select=".content"></ng-content>
</div>
Enter fullscreen mode Exit fullscreen mode

父内容

<div>
  <greet>
    <h3> everything else </h3>
    <h1> Header </h1>
    <span class="content"> something </span>
  </greet>
</div>
Enter fullscreen mode Exit fullscreen mode

内容投影后的输出是

<div>
  <div class="container">
    <h3> everything else </h3>
    <h1> Header </h1>
    <p>welcome text</p>
    <span class="content"> something </span>
</div>
</div>
Enter fullscreen mode Exit fullscreen mode

参考

内容儿童和内容儿童

访问投影内容

CardComponent.html

<div class="card">
   <ng-content select="header"></ng-content>
   <ng-content select="content"></ng-content>
   <ng-content select="footer"></ng-content>
</div> 
Enter fullscreen mode Exit fullscreen mode

CardComponent.ts

@ContentChild("header") cardContentHeader: ElementRef;
Enter fullscreen mode Exit fullscreen mode

ParentComponent.html

<card>
  <header><h1 #header>Angular</h1></header>
  <content>One framework. Mobile & desktop.</content>
  <footer><b>Super-powered by Google </b></footer>
</card>
Enter fullscreen mode Exit fullscreen mode

tektutorialshub提供了一份简明扼要的说明。

静态标志

static 默认设置为 false。
之所以设置为 false,是因为我们希望每次变更检测都能解析查询。

Angular 文档Stack Overflow 上对该标志有更详细的描述。

ViewChild、ViewChildren、ContentChild、ContentChildren

ViewChild:从自身视图访问 DOM 元素; ContentChild:从另一个
视图 访问 DOM 元素,或访问由其他人投影的 DOM 元素 (例如,元素位于 CardComponent.ts 中,但投影内容来自 ParentComponent.html)。
@ContentChild

ViewChildren:ViewChild 的集合;
ContentChildren:ContentChildren 的集合

在 Angular 中发起 HTTP 请求

  1. @angular/common/http
  2. 在 Angular 模块中导入 HttpModule
  3. 通过依赖注入创建 HttpClient 对象constructor(public http:HttpClient)
  4. 使用 HttpClient 创建 POST/GET 类this.http.post(URL, data).subscribe(res => successfunc(res), err => errfunc(err)
  5. 订阅 Http.post / Http.get。Subscribe 接受两个输入:成功函数和错误函数。

需要订阅功能

如果 HTTP 调用成功/失败,则需要提供成功/错误处理方法。
此外,如果没有异步管道,则需要订阅才能使可观察对象执行。

处理 HTTP 调用中的错误

  1. 订阅方法的错误回调
  2. catchError管道中的函数。(catchError 必须返回一个新的 Observable 或抛出一个错误)当抛出新的错误时,抛出的错误会传递给订阅者。更多详情请参见tekturotials。

第二种方法在 Angular 中实现了关注点分离
。 此外,
还可以链式调用多个可观察对象(一个接一个)。

  • catchError保持可观察对象存活。如果内部可观察对象出现错误,外部可观察对象仍会继续执行(因为它接收到了可观察对象)。合并多个可观察对象(执行多个可观察对象)。
  • 允许可观察对象数组完成。否则,如果只有一个可观察对象失败,则所有可观察对象都会失败,而catchError允许该可观察对象完成并发出一些信息。

在组件和路由之间传递数据

  1. 父子组件
    @Input:父组件 -> 子组件
    @Output:子组件 -> 父组件
    @ViewChild

  2. 路由间的数据 -> 路由查询参数

this.route.navigate(['url'],
  {queryParams: {
    name: 'myname'
    }
   });
Enter fullscreen mode Exit fullscreen mode
  1. 服务更多地侧重于全球数据/存储更多地通过单例服务共享全球数据
  2. 创建服务
  3. 将服务注入组件
  4. 访问服务数据

  5. 浏览器
    *全局数据 *
    本地存储/临时存储

使用服务传递数据的良好实践

共享数据传递数据:
如果您只是在组件之间传递数据,则应避免使用服务/全局变量。
其他组件可能会修改全局变量,导致代码变得非常混乱。

为什么需要角形管?

管道用于转换 Angular UI 表达式中的数据。Angular
内置了一些管道:

  1. AsynPipe:从异步源读取对象(默认情况下是不纯的)
  2. JsonPipe:将对象转换为 JSON 字符串
  3. KeyValuePipe:可在 ngFor 中用于遍历对象的键和值。
  4. DatePipe:格式日期
  5. CurrencyPipe:数字 -> 货币字符串

例子:

<p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} </p>
Enter fullscreen mode Exit fullscreen mode

你还可以串联管道(先实现第一个管道,然后将第二个管道的输出连接到第一个管道的输出)。

{{ birthday | date | uppercase}}
Enter fullscreen mode Exit fullscreen mode

如何在Angular中创建自定义管道?

  1. 用于@Pipe将类标记为管道
  2. 实现 PipeTransform 接口
  3. 实现 transform 方法。
@Pipe({name: 'uselessPipe'})
export class uselessPipe implements PipeTransform {
  transform(value: string, before: string, after: string): string {
    let newStr = `${before} ${value} ${after}`;
    return newStr;
  }
}

{{ user.name | uselessPipe:"Mr.":"the great" }}
Enter fullscreen mode Exit fullscreen mode

角形管道中的变化检测。

  1. 数据可以是原始输入值(字符串、数字)或对象引用(日期/数组)。Angular
    会在检测到引用的输入值发生变化时执行管道操作。

  2. 修改复合对象内部的内容(例如日期中的月份、数组元素、对象属性)
    可以使用impure管道符。

参考自 Angular文档

检测对基本元素和对象引用的纯粹更改

Angular 管道默认是函数。Angular仅在检测到输入值发生纯变化时才会执行管道操作。纯变化是指:

  1. 更改为 pimitive 输入string,,,numberbooleansymbol
  2. 更改对象引用Date,,,ArrayFunctionObject

在纯管道中,Angular 会忽略组件对象内部的变化(例如,向现有数组添加新元素),因为对象引用没有改变。

例子:

<div *ngFor="let hero of (heroes | flyingHeroes)">
  {{hero.name}}
</div>

@Pipe({ name: 'flyingHeroes' })
export class FlyingHeroesPipe implements PipeTransform {
  transform(allHeroes: Hero[]) {
    return allHeroes.filter(hero => hero.canFly);
  }
}
Enter fullscreen mode Exit fullscreen mode

如果用户添加了飞行英雄,由于数组引用没有改变,Angular 不会更新显示,因此飞行英雄的显示不会更新。有两种方法可以解决这个问题。

  1. 更改对象引用,将数组替换为包含新更改元素的新数组,并将新数组输入到管道。
  2. 使管道检测不纯更改,并将纯净标志设置为 false
@Pipe({
  name: 'flyingHeroesImpure',
  pure: false
})
Enter fullscreen mode Exit fullscreen mode

什么是变化检测

Angular 将应用程序 UI 状态与数据状态同步的机制

当组件数据更新时(例如,来自用户事件/应用程序逻辑),视图中绑定到 DOM 属性的值可能会发生变化。变更检测器负责更新视图以反映当前的数据模型。

参考资料:Angular文档

同步与异步

同步代码按顺序执行。
当一条语句正在执行时,其他语句都无法执行。

异步代码无需等待——你的程序可以持续运行。
异步代码在同步 JavaScript 中很难实现,开发者无法确定代码需要多长时间才能完成(例如,从 API 下载图片需要多长时间?)。
因此,像这样的代码:

let response = fetch('myImage.png'); // fetch is asynchronous
let blob = response.blob();
// display your image blob in the UI somehow
Enter fullscreen mode Exit fullscreen mode

blob 可能未定义。
异步 JavaScript 主要有两种代码风格:

  1. 回调函数(旧式)
  2. 承诺(新式)

异步 JavaScript 有两种模型:(更多详情请参见RxJS)

  1. 拉取模式(消费者为王,消费者决定何时从生产者接收数据,生产者不知道数据何时交付)
  2. 推送模式(生产者为王,决定何时向消费者发送数据)

Promise 和 Observable 都遵循推送模型。Promise
(生产者)将解析后的值传递给已注册的回调函数(消费者)。

更多信息请参见此处MDN网站。

什么是 RxJS?

RxJS 代表JavaScript 的响应式扩展。

它用于处理异步数据流,
例如异步数据源(HTTP 数据、定时器)可能需要 1 秒或 15 秒才能到达。因此,应用程序应该有一个监听器
(例如,HTTP 响应,数据以较小的时间间隔到达)。

RxJs 可以帮助您轻松处理异步数据流。

什么是可观测变量和观察者?

Observable 是 JavaScript 的一个推送系统。它是一个生产多个值并将其“推送”给观察者(消费者)的机制。

Observable 可以同步或异步地提供多个值。

这篇freecodecamp文章有非常全面的介绍。

可观测性分为4 个主要阶段

  1. 创建
  2. 订阅
  3. 执行
  4. 处置

RxJS 中 subscribe 的重要性

每次调用都会observable.subscribe为指定的订阅者触发独立的设置。RxJS :启动一个“可观察执行”,并将值/事件传递给执行的观察者。Angular :只有当有人订阅时,可观察实例才会开始发布

如何取消订阅(可观测对象的销毁阶段)

摘自RxJS文档

const subscription = observable.subscribe(x => console.log(x));
subscription.unsubscribe();
Enter fullscreen mode Exit fullscreen mode

由于 Observable 的执行次数可能无限循环,而观察者通常会在有限时间内中止执行,因此我们需要一个用于取消执行的 API。当执行停止/取消时,我们可以避免浪费计算能力/内存资源。

用示例代码解释运算符的概念

运算符也是函数。
运算符分为两种类型:

  1. Pipeable 操作符以可观察对象作为输入,输出也是一个可观察对象。预处理逻辑可以转换可观察对象中的数据。
  2. 创建运算符可以作为独立函数调用,以创建新的 Observable。

摘自RxJS文档

文章来源:https://dev.to/jing/angular-theory-553p