当前位置: 首页 > article >正文

Angular进阶之十:toPromise废弃原因及解决方案

背景

Rxjs从V7开始废弃了toPromise, V8中会删除它。

原因

1:toPromise()只返回一个值

toPromise()将 Observable 序列转换为符合 ES2015 标准的 Promise 。它使用 Observable 序列的最后一个值。

例:

import { Observable } from "rxjs";
……
myObservable = new Observable<string>((observer) => {
    observer.next('Hello');
    observer.next('World');
    observer.complete();
});

获取并打印结果,toPromise()后只获取了最后一个结果'World'

this.myObservable.toPromise().then((value: string) => {
      console.log(`toPromise: ${value}`);
});

2:Observable 可能不产生值或产生多个值

Observable 和 Promise 之间的相似之处在于,两者都可能随着时间的推移产生值,但不同之处在于,Observable 可能不产生值或产生多个值,而 Promise在成功解析时仅产生一个值。

例:增加代码如下

this.myObservable.subscribe((value: string) => {
      console.log(`observable: ${value}`);
});

Observable产生两个值

如果我们注释掉下面代码,Observable不产生值但Promise产生一个undefined值,

myObservable = new Observable<string>((observer) => {
    // observer.next('Hello');
    // observer.next('World');
    observer.complete();
});

因此,在V7 中,Observable 的 toPromise() 方法的返回类型已修复,以更好地反映 Observable 可以产生零值的事实。对于某些项目来说,这可能是一个重大变化,因为返回类型已从 Promise<T> 更改为 Promise<T | undefined>。

3:toPromise() 方法名不明确

toPromise() 方法名称从未指示 Promise 将解析为发出的哪个值,因为 Observable 可以随时间产生多个值。转换为 Promise 时,您可能希望选择要选择哪个值 - 第一个到达的值或最后一个值。为了解决所有这些问题,rxjs决定弃用 toPromise(),

解决方案

作为已弃用的 toPromise() 方法的替代,您应该使用两个内置静态转换函数 firstValueFrom 或 lastValueFrom。

1:lastValueFrom

lastValueFrom 几乎与 toPromise() 完全相同,这意味着它将在 Observable 完成时解析为到达的最后一个值。

例:增加代码

const lastValue = await lastValueFrom(this.myObservable);
console.log(`lastValueFrom: ${lastValue}`);

但当 Observable 完成而未发出值时,行为有所不同。当 Observable 完成而未发出时,toPromise() 将成功解析为 undefined(因此返回类型会发生变化),而 lastValueFrom 将拒绝并返回 EmptyError。因此,lastValueFrom 的返回类型是 Promise<T>,就像 RxJS 6 中的 toPromise() 一样。

例:

myObservable = new Observable<string>((observer) => {
    // observer.next('Hello');
    // observer.next('World');
    observer.complete();
});
this.myObservable.toPromise().then((value: string | undefined) => {
      console.log(`toPromise: ${value}`);
});
const lastValue = await lastValueFrom(this.myObservable);
console.log(`lastValueFrom: ${lastValue}`);

2:firstValueFrom

但是,您可能希望在第一个值到达时立即获取它,而不等待 Observable 完成,因此您可以使用 firstValueFrom。firstValueFrom 将使用 Observable 发出的第一个值解析 Promise,并立即取消订阅以保留资源。

例:增加代码

const firstValue = await firstValueFrom(this.myObservable);
console.log(`firstValueFrom: ${ firstValue}`);

如果 Observable 完成且未发出任何值,firstValueFrom 也会拒绝并出现 EmptyError。

例:

myObservable = new Observable<string>((observer) => {
    // observer.next('Hello');
    // observer.next('World');
    observer.complete();
});
this.myObservable.toPromise().then((value: string | undefined) => {
      console.log(`toPromise: ${value}`);
});
const firstValue = await firstValueFrom(this.myObservable);
console.log(`firstValueFrom: ${ firstValue}`);

默认值

无论是哪种替代方案,我们都可以设置默认值,以防止EmptyError发生。

例:

const firstValue = await firstValueFrom(this.myObservable, { defaultValue: "''" });
console.log(`firstValueFrom: ${ firstValue}`);
const lastValue = await lastValueFrom(this.myObservable, { defaultValue: "''" });
console.log(`lastValueFrom: ${lastValue}`);

最后

仅当您知道 Observable 最终会完成时才使用 lastValueFrom 函数。如果您知道 Observable 将发出至少一个值或最终会完成,则应使用 firstValueFrom 函数。

如果源 Observable 未完成或未发出,您最终会得到一个挂起的 Promise,并且异步函数的所有状态都可能挂在内存中。

为了避免这种情况,请考虑添加 timeouttaketakeWhiletakeUntil 等。


http://www.kler.cn/a/383720.html

相关文章:

  • Unity复刻胡闹厨房复盘 模块一 新输入系统订阅链与重绑定
  • Rust 在前端基建中的使用
  • ubuntu 网络管理
  • ECharts散点图-气泡图,附视频讲解与代码下载
  • springBoot Maven 剔除无用的jar引用
  • JavaScript中的Set、Map、WeakSet和WeakMap
  • 【java】实战-力扣题库:二分查找
  • 首都师范大学地信GIS导师推荐(避坑)
  • 从 vue 源码看问题 — 如何理解 vue 响应式?
  • 【贪心算法】No.1---贪心算法(1)
  • 量子电路的实现 基于ibm的qiskit
  • 基于MySQL的企业专利数据高效查询与统计实现
  • 【日记】跟人沟通有时真的好头疼(688 字)
  • 年入百万:从初中辍学到 50 万读者!
  • npm i忽略依赖冲突
  • Java | Leetcode Java题解之第541题反转字符串II
  • 国产linux系统openeuler24.03安装gnome桌面环境后优化
  • 【MissModal】提高多模态情感分析对缺失情态的鲁棒性
  • 网络安全从入门到精通(特别篇I):应急响应之APT事件处置流程
  • android10 蓝牙(一)开关与扫描源码解析
  • STM32Cube高效开发教程<高级篇><FreeRTOS>(十二)-----互斥量使用例程
  • Java学习Day58:相声二人组!(项目统计数据Excel图表导出)
  • 前端八股文(一)HTML 持续更新中。。。
  • 如何用PPT画箭头?用这2个ppt软件快速完成绘图!
  • 文件操作:Xml转Excel
  • Git代码托管(三)可视化工具操作(1)