在 Angular2 中,RxJS(Reactive Extensions for JavaScript)是一种非常流行的响应式编程框架。它提供了一种声明式、响应式的方式来处理异步数据流,并且结合 Angular2 的组件式开发,可以帮助我们编写更为简洁、高效的代码。
在上一篇文章中,我们介绍了 RxJS 的基本概念和使用方式。本文将进一步讨论在 Angular2 中如何使用 RxJS,并包含一些示例代码。
Observable 和 Subject
在 Angular2 中,RxJS 的核心是 Observable 和 Subject。Observable 是一个数据流,可以表示任何异步数据,如 HTTP 请求的响应、用户事件、时间间隔等等。而 Subject 是一个特殊的 Observable,可以让我们在数据流中向多个观察者同时发送数据。
基本使用方式
Observables 有很多方法来处理它们所表示的数据,例如 map、filter、merge、scan 等等。我们可以通过 import {Observable} from 'rxjs/Observable' 来导入 Observable,并在代码中使用它。
下面是一个简单的 Observable 示例:
// javascriptcn.com 代码示例 import {Observable} from 'rxjs/Observable'; import 'rxjs/add/observable/of'; const observable = Observable.of('hello', 'world'); observable.subscribe({ next: value => console.log(value), error: error => console.error(error), complete: () => console.log('complete') });
这段代码中,我们使用 of 方法创建了一个 Observable,然后订阅它并输出它所发射的值。
使用 Operators
Observable 的真正威力在于它能够使用 Operators 来变换数据流。Operators 本质上是纯函数,用来接收一个 Observable 并返回一个新的 Observable。这使得我们可以组合多个 Operators 来处理数据流,从而实现复杂的异步数据逻辑。
RxJS 提供了很多内置的 Operators,包括 map、filter、reduce、merge、concat、delay 等等。我们可以使用 import {map, filter} from 'rxjs/operators' 来导入这些 Operators。
下面是一个使用 Operators 的示例代码:
// javascriptcn.com 代码示例 import {Observable} from 'rxjs/Observable'; import {map} from 'rxjs/operators'; const observable = Observable.of('hello', 'world'); observable.pipe( map(value => value.toUpperCase()) ).subscribe({ next: value => console.log(value), error: error => console.error(error), complete: () => console.log('complete') });
这里我们使用 of 方法创建了一个 Observable,然后使用 map Operator 将它所发射的值转换为大写形式。
Subject 的使用
Subject 是一个专门用于多播的 Observable。与 Observable 不同的是,Subject 不仅可以发射数据,还可以订阅数据。这使得我们可以在多个观察者之间共享数据,并且可以在任何时间点向 Subject 发射新数据。
下面是一个示例代码:
// javascriptcn.com 代码示例 import {Subject} from 'rxjs/Subject'; const subject = new Subject(); subject.subscribe({ next: value => console.log(`subscriber 1: ${value}`) }); subject.next('hello!'); subject.subscribe({ next: value => console.log(`subscriber 2: ${value}`) }); subject.next('world!');
这里我们使用 Subject 创建了一个数据流,并且向它添加了两个观察者。当我们调用 subject.next(value) 时,它会向所有观察者发送新的数据。
在 Angular2 中使用 RxJS
在 Angular2 中使用 RxJS 是非常常见的。我们可以使用它来处理用户输入、HTTP 请求的响应、定时器和其他异步操作。在 Angular2 的官方文档中,我们可以看到很多实际的例子,例如:
// javascriptcn.com 代码示例 import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/map'; @Component({ selector: 'my-app', template: 'Hello, {{name}}!<br> {{message}}' }) export class AppComponent { name = 'Angular'; message: string; constructor(http: HttpClient) { this.message = 'Loading data...'; http.get('data.json') .map(response => response.json().message) .subscribe(message => this.message = message); } }
这里我们使用 HttpClient 来加载 data.json 文件,并将它的 message 属性显示在模板中。
另一个常用的示例是在组件中处理用户输入:
// javascriptcn.com 代码示例 import { Component } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/map'; @Component({ selector: 'my-app', template: ` <h1>{{name}}!</h1> <input type="text" [(ngModel)]="searchQuery"> <ul> <li *ngFor="let result of searchResults">{{result}}</li> </ul>` }) export class AppComponent { name = 'Angular'; searchQuery: string; searchResults: string[]; constructor() { // Create an Observable that emits search requests const searchQuery$: Observable<string> = Observable.fromEvent(document.querySelector('input'), 'input') .map((event: KeyboardEvent) => (<HTMLInputElement>event.target).value); // Filter out any search queries fewer than 3 characters long const validSearchQuery$: Observable<string> = searchQuery$.filter(query => query.length >= 3); // Debounce the search queries by 300ms const debouncedSearchQuery$: Observable<string> = validSearchQuery$.debounceTime(300); // Use switchMap to switch into a new Observable of search results every time // the user enters a search query const searchResults$: Observable<string[]> = debouncedSearchQuery$.switchMap(query => this.search(query)); // Subscribe to the search results searchResults$.subscribe(results => this.searchResults = results); } search(query: string): Observable<string[]> { // Do an HTTP request to get search results const url = `https://api.github.com/search/repositories?q=${query}`; return Observable.fromPromise(fetch(url).then(response => response.json())) .map(response => response.items && response.items.length > 0 ? response.items.map(item => item.full_name) : []); } }
这个示例中,我们在 input 元素上监听 input 事件,并使用 debounceTime Operator 来减少搜索请求的频率。然后,我们使用 switchMap Operator 来在每次输入搜索词时自动发出 HTTP 请求,并用 Angular2 的 ngFor 指令显示搜索结果。
总结
RxJS 是 Angular2 的一个重要组成部分,它提供了一种简洁、响应式的方式来处理异步数据。我们可以使用 Operators 来组合多个 Observable,以实现复杂的异步数据逻辑。在 Angular2 中,RxJS 是开发响应式、高效和流畅的应用程序的一个非常有用的库。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653f21657d4982a6eb8a838b