Angular 中RxJS 和 HttpClient 总结
1. HttpClientModule 与 provideHttpClient() 的使用
- 从 Angular 14 开始,推荐使用新的
provideHttpClient()方式注册HttpClient,无需显式导入HttpClientModule。 - 与独立组件架构兼容性更强,模块化设计更简洁。
示例:import { provideHttpClient } from '@angular/common/http'; import { ApplicationConfig } from '@angular/core'; export const appConfig: ApplicationConfig = { providers: [ provideHttpClient() ] };
2. HttpClient 和 RxJS 的核心功能与逻辑
- HTTP 请求: 使用
HttpClient提供的get、post等方法发送请求。 - 返回值: 所有方法返回的是
Observable,适合响应式编程。 - 数据处理: 使用
RxJS操作符(如map、catchError)对响应数据进行处理。 - 订阅: 只有调用
subscribe()才会触发 HTTP 请求,因为Observable是冷流。
3. 调用 subscribe 的必要性
HttpClient返回的Observable是惰性求值的,调用subscribe后才能执行请求。
示例:this.articlewatchvideoService.getList<ArticlewatchvideoFilter>(filter) .subscribe({ next: (result) => console.log('成功返回数据:', result), error: (err) => console.error('请求出错:', err) });
4. 使用 pipe() 链式处理数据
pipe() 用于对 Observable 流进行操作,常见应用:
- 数据转换:
map()转换服务器返回的数据结构。 - 错误处理:
catchError()捕获错误并提供替代流。 - 流过滤:
filter()筛选符合条件的数据。
示例:
this.articlewatchvideoService.getList<ArticlewatchvideoFilter>(filter)
.pipe(
map((res) => res.data), // 提取 `data` 字段
catchError((error) => {
console.error('错误处理:', error);
return throwError(() => error); // 抛出错误
})
)
.subscribe((data) => console.log('处理后的数据:', data));
5. lastValueFrom:将 Observable 转换为 Promise
- 功能: RxJS 提供的工具函数,用于同步方式获取
Observable的最后一个值。 - 适用场景: 在需要
async/await的异步逻辑中使用。 - 注意: 转换后无需
subscribe,但仍可使用操作符对数据流处理。
示例:
import { lastValueFrom } from 'rxjs';
const result = await lastValueFrom(
this.articlewatchvideoService.getList<ArticlewatchvideoFilter>(filter)
);
console.log('返回的数据:', result);
6. Observable 与 lastValueFrom 的对比与适用场景
Observable + subscribe:- 更适合响应式编程和流式处理。
- 可多次订阅,适用于实时更新数据的场景。
lastValueFrom:- 适合一次性获取数据,与异步函数结合时更简洁。
- 如果项目广泛采用
Observable,可以减少对lastValueFrom的依赖。
关于 lastValueFrom 和 Observable 的意义与机制
1. lastValueFrom 和 Observable 的对比及意义
使用场景差异
-
Observable:- 本质是一个数据流,支持异步、多次推送和响应式编程。
- 适用于需要处理数据流、实时更新、链式操作符的场景。
-
lastValueFrom:- 本质是一个工具,将
Observable转换为Promise,更适合一次性获取数据并与async/await结合。 - 适用于传统同步逻辑,尤其是在需要与其他异步操作结合的场景。
- 本质是一个工具,将
是否有意义
- 如果项目中仅需要一次性获取 HTTP 数据且无复杂流式处理需求,直接使用
Promise可能更直观(如 Angular 6 之前的HttpClient默认返回Promise)。 - 然而,
lastValueFrom的意义在于:- 让已有基于
Observable的 API 与同步编程(如async/await)兼容。 - 对于已经使用
Observable的逻辑,不必重写为Promise,而是直接转换。
- 让已有基于
2. Observable 的冷流机制
冷流与热流的区别
-
冷流 (Cold Observable): 数据流的生产者 在订阅时 开始工作。
- 例如:
HttpClient返回的Observable,只有在调用subscribe()时才会真正发起 HTTP 请求。 - 每个订阅者获取的是独立的流。
- 例如:
-
热流 (Hot Observable): 数据流的生产者与订阅无关,它始终在“发送数据”,所有订阅者共享同一个流。
- 例如:鼠标事件、
Subject等。
- 例如:鼠标事件、
为什么 Observable 是冷流
Angular 的 HttpClient 返回的 Observable 是冷流,这是为了:
- 惰性求值: 避免在未订阅时就触发不必要的 HTTP 请求。
- 独立性: 每次订阅都是独立的请求,互不干扰,便于控制。
订阅触发请求的机制
HttpClient返回的Observable包含请求的配置与逻辑,但请求并未真正发送。- 只有当调用
subscribe()时,Observable会触发数据生产逻辑,进而发送 HTTP 请求并推送数据给订阅者。
示例解释
const obs$ = this.httpClient.get('/api/data'); // 创建了一个冷流,没有发送请求
obs$.subscribe(data => console.log('订阅1:', data)); // 此时才发送请求
obs$.subscribe(data => console.log('订阅2:', data)); // 第二次订阅会再次发送请求
说明:
- 两次
subscribe()独立触发了两次 HTTP 请求,因为Observable是冷流。 - 如果需要共享流,可以使用
shareReplay()或Subject将其转化为热流。
3. 总结:为何需要订阅和冷流机制
Observable的冷流机制提供了更多灵活性,避免不必要的资源消耗。- 通过订阅来触发请求,赋予开发者对请求执行的完全控制权。
lastValueFrom是一种与同步编程兼容的工具,但它不取代Observable的响应式能力,只是针对特定场景的一种优化手段。
取消订阅.unsubscribe()的情况:
-
普通的 HTTP 请求:
- 一次性请求:当你使用像
HttpClient的get()或post()这样的 HTTP 方法时,Observable代表的是一个冷流(Cold Observable),即发起一次 HTTP 请求,等待服务器响应并处理返回数据。请求完成后,Observable会自动完成,subscribe()会结束,不需要特意去取消订阅。 - 不需要取消订阅:因为 HTTP 请求是一次性的,
Observable在请求响应完成后自动结束,所以即使不取消订阅,也不会造成内存泄漏或不必要的资源占用。
- 一次性请求:当你使用像
-
WebSocket 或其他持续的数据流:
- 持续的连接:WebSocket、
interval()、fromEvent()等会创建持续的数据流,这些数据流是热流(Hot Observable),一旦建立连接或订阅,Observable会持续发出新的数据(例如每秒钟推送一个新消息,或者实时接收服务器推送的数据)。 - 需要取消订阅:因为数据流是持续的,它会一直保持激活,直到你手动取消订阅。否则,它会占用资源并继续运行,导致潜在的内存泄漏或不必要的网络请求。
- 持续的连接:WebSocket、
- HTTP 请求:无需特别取消订阅,它会自动结束。
- WebSocket 或持续数据流:需要取消订阅,以释放资源并停止数据流。
通过取消订阅,你能确保不再接收不必要的数据,并且能释放资源,避免内存泄漏或不必要的网络活动。
745

被折叠的 条评论
为什么被折叠?



