返回

RxJS 6 中被废弃的 toPromise(译)

前端

引言

RxJS 7 中,Observable 的 toPromise 方法已被废弃,因为它存在以下几个问题:

  • 不规范: toPromise 方法不是 RxJS 操作符的规范名称。
  • 语义不清: 该方法的名称暗示它将 Observable 转换为 Promise,但实际上它不会创建一个新的 Promise。
  • 效率低下: toPromise 方法需要订阅 Observable 并在 Observable 完成时调用 Promiseresolve 方法。这可能会降低性能,尤其是在 Observable 延迟发出值的情况下。

替代方案

在 RxJS 7 中,有几种方法可以将 Observable 转换为 Promise:

  • 使用 last 操作符: last 操作符会发出 Observable 的最后一个值,并完成。这允许你使用 .toPromise() 方法将 Observable 转换为 Promise:
import { last } from 'rxjs/operators';

const observable = Rx.interval(1000);

observable.pipe(last()).toPromise().then(value => console.log(value));
  • 使用 reduce 操作符: reduce 操作符可以累积 Observable 发出的值,并最终返回一个值。这允许你使用 .toPromise() 方法将 Observable 转换为 Promise:
import { reduce } from 'rxjs/operators';

const observable = Rx.interval(1000);

observable.pipe(reduce((acc, value) => acc + value, 0)).toPromise().then(value => console.log(value));

为什么弃用 toPromise 方法

toPromise 方法存在几个缺陷,使得它在 RxJS 7 中被废弃:

  • 语义不清: 该方法的名称暗示它会将 Observable 转换为 Promise,但实际上它不会创建一个新的 Promise。相反,它订阅 Observable 并在 Observable 完成时调用 Promiseresolve 方法。这可能会导致混乱,并可能导致意外行为。
  • 效率低下: toPromise 方法需要订阅 Observable 并等待它完成。这可能会降低性能,尤其是在 Observable 延迟发出值的情况下。
  • 不一致: toPromise 方法在不同的 RxJS 版本中行为不一致。在 RxJS 5 中,它返回一个 Promise,而在 RxJS 6 中,它返回一个 Observable。这使得难以编写可移植的代码。

迁移到替代方案

如果你使用的是 RxJS 6,并且你的代码依赖于 toPromise 方法,你需要迁移到替代方案。建议的方法是使用 lastreduce 操作符。

要使用 last 操作符,你需要安装 rxjs-compat 包:

npm install rxjs-compat

然后,你可以使用以下代码将 Observable 转换为 Promise:

import { last } from 'rxjs/operators';
import { Observable } from 'rxjs-compat';

const observable = Rx.interval(1000);

observable.pipe(last()).toPromise().then(value => console.log(value));

要使用 reduce 操作符,你需要使用 RxJS 7 中的 reduce 操作符:

import { reduce } from 'rxjs/operators';

const observable = Rx.interval(1000);

observable.pipe(reduce((acc, value) => acc + value, 0)).toPromise().then(value => console.log(value));

结论

toPromise 方法在 RxJS 7 中被废弃,因为它存在语义不清、效率低下和不一致的问题。建议使用 lastreduce 操作符作为替代方法。通过迁移到这些替代方案,你可以提高代码的性能、可维护性和可移植性。