RXJS 中的 startWith 运算符真的被弃用了吗?

Posted

技术标签:

【中文标题】RXJS 中的 startWith 运算符真的被弃用了吗?【英文标题】:Is the startWith operator in RXJS really deprecated? 【发布时间】:2019-10-27 12:16:18 【问题描述】:

自从更新到 RXJS 版本 6 后,我的 WebStorm 编辑器一直在抱怨 一些 使用 startWith() 操作符被标记为已弃用

您可以在源代码中看到这些方法被标记为已弃用:

Link to master (Harder link for future)

对我来说,问题是不推荐使用的警告不一致。有时它会报告已弃用的方法,有时则不会。虽然我可以在下面的代码示例中重现警告。它似乎随机发生在我自己的源代码中。

不推荐使用:

  of(false).pipe(startWith(true));

被标记为弃用:

  const x: any = true;
  of(false).pipe(startWith(x));

所以我担心这些已弃用的警告。弃用消息说要改用 scheduled()concat() 运算符,但这感觉比 startWith() 等已经很方便的运算符更复杂。

所以我有点困惑为什么它被弃用,以及为什么它只是有时被弃用。

【问题讨论】:

没有。 github.com/ReactiveX/rxjs/issues/4772 @cartant 啊。我现在明白了。如果你愿意,那应该是答案。 时间紧迫。如果您能自己回答您的问题,我将不胜感激。我在我的 TODO 列表中添加了一条注释以改进弃用消息。还有这个问题:github.com/ReactiveX/rxjs/issues/4776 @cartant 没问题。感谢您在 rxjs 上所做的所有出色工作。 【参考方案1】:

不,不是。

目前只有一个活跃签名:startWith(...values)

除了这个签名,它还有几个接受scheduler: SchedulerLike作为最新参数的重载:startWith(...values, scheduler),这个功能已经被弃用了。

如果您不将schedulerstartWith 一起使用,则可以。

如果你这样做了,那么你需要使用 scheduled 函数重写你的代码,就像他们在折旧注释旁边的评论中建议的那样:scheduled([[a, b, c], source], scheduler).pipe(concatAll())


很有可能,您正在使用 startWith(null)startWith(undefined),尽管有通知,但它们并未被弃用,但 IDE 检测到错误的函数签名已被弃用,并显示警告。

或者,您正在使用formControl.valueChanges,它发出any 类型,或任何其他带有any 的可观察流。因为anySchedulerLike 匹配,所以您会看到通知。

因此,通过添加filter((v): v is number => typeof === 'number') 或任何其他可能的方式尽量避免any

【讨论】:

对于其他人在使用 null 作为起始值时发现此问题,打字稿编译器认为您可能正在使用重载 startWith<T>(scheduler: SchedulerLike),这就是出现警告的原因。 我发现使用 startWith(null) 的错误在这种情况下我应该删除 startWith 吗? 如果由于使用 startWith(null) 或 startWith(undefined) 而出现警告,则警告是错误的,可能会被忽略。但是您可以通过将 null 或 undefined 转换为某种类型来修复它。它可能是某种相关的 Observable 类型,或者只是一些不相关的类型,例如开始(空)。编辑:实际上 Anh-Thi DINH 已经 posted it below.【参考方案2】:

对于那些在使用startWith(null) 时在 VSCode 中看到已弃用警告的人,只需将其替换为 startWith(<string>null) 即可解决警告消息。

更多信息是here。

【讨论】:

【参考方案3】:

避免弃用通知的一种方法是将您传递给startWith 的任何内容进行类型转换。例如 OP 示例中的 startwith(x as boolean)

这样,您可以向 IDE 保证您没有使用已弃用的签名。

【讨论】:

【参考方案4】:

当我尝试startWith(undefined) 时,我也收到了一条已弃用的消息 原因是它默认为 export declare function startWith<T>(scheduler: SchedulerLike): MonoTypeOperatorFunction<T>; 已弃用的 API

修复是指定返回类型D(未定义的): export declare function startWith<T, D>(v1: D): OperatorFunction<T, T | D>;

例如,假设我有接口 MyType1,我的 observable 将其映射到 myType2startWith<MyType1, MyType1>(undefined)

【讨论】:

【参考方案5】:

这个技巧效果很好:

startWith<void, void>(undefined);

【讨论】:

以上是关于RXJS 中的 startWith 运算符真的被弃用了吗?的主要内容,如果未能解决你的问题,请参考以下文章

[RxJS] Displaying Initial Data with StartWith

RxJS Observable Share startWith() state in merge()

如果ReplaySubject在RXJS中没有发出任何值,则startWith操作符。

不推荐使用 Rxjs toPromise()

Rxjs:扫描操作符

rxjs Observable 两大类操作符简介