combineLatest 重构 @deprecated — 不再支持 resultSelector,而是使用管道映射?

Posted

技术标签:

【中文标题】combineLatest 重构 @deprecated — 不再支持 resultSelector,而是使用管道映射?【英文标题】:combineLatest refactoring for @deprecated — resultSelector no longer supported, pipe to map instead? 【发布时间】:2021-01-21 22:24:00 【问题描述】:

Angular 材质文档应用程序中包含以下 sn-p:

    // Combine params from all of the path into a single object.
    this.params = combineLatest(
      this._route.pathFromRoot.map(route => route.params),
      Object.assign);

TSLint 删除 combineLatest 并带有此消息:

@deprecated — 不再支持 resultSelector,改为通过管道映射

应该如何解决?

此外,如果您了解所使用的技术,那么一个简单的详细示例将会很棒。

这是一个代码链接:

https://github.com/angular/material.angular.io/blob/master/src/app/pages/component-category-list/component-category-list.ts

【问题讨论】:

【参考方案1】:

pipe 结果并改用map 运算符,例如:

combineLatest(this._route.pathFromRoot.map(route => route.params)).pipe(
  map(Object.assign)
);

Reference

另外,不确定代码的意图,因为它似乎在新数组引用上调用 Object.assign,不知道为什么这是必要的,但这并不完全相关。

【讨论】:

是的...我也没有真正理解Object.assign 的意图...仅查看代码似乎他们可以做到this.params = this._route.pathFromRoot.map(route => route.params) ... 我在问题中添加了我认为他们可以做的事情......你觉得有什么问题吗? 我并不熟悉该库中的所有位,但使用 Object.assign 似乎不合适,但也许我错过了一些上下文。【参考方案2】:

结果选择器只是一个可以用来改变输出形状的函数。

因此,您可以简单地省略结果选择器参数并使用映射来转换形状:

    this.params = combineLatest(
      this._route.pathFromRoot.map(route => route.params)
    ).pipe(
        map(Object.assign)
    );

结果选择器的一个常见用途(无论如何对我来说)是将数组作为具有命名属性的对象返回,因此如下所示:

// 老路

myObs$ = combineLatest(
   [src1$, src2$, src3$], 
   ([src1, src2, src3]) => (src1, src2, src3)
);

// 新方法

myObs$ = combineLatest(src1$, src2$, src3$)
    .pipe(
       map(([src1, src2, src3]) => (src1, src2, src3))
    );

【讨论】:

我克隆了源码并试了一下。它停止渲染。有什么想法吗? 你的意思是 observable 不再发射?编辑:我刚看到@fridoo 的回答 :-)【参考方案3】:
combineLatest(observables, resultSelector)

通常可以替换为

combineLatest(observables).pipe(
  map(resultSelector)
)

但这是否以相同的方式工作取决于您的resultSelector 接受的参数。当您使用已弃用的 resultSelector 时,combineLatest(observables) 会发出一个数组和 RxJs automatically spreads this array。

return isArray(args) ? fn(...args) : fn(args); // fn is your resultSelector

Object.assign 返回不同的值,具体取决于您提供的是数组还是多个值,您必须手动展开数组。

combineLatest(observables).pipe(
  map(items => Object.assign(, ...items))
)

【讨论】:

以上是关于combineLatest 重构 @deprecated — 不再支持 resultSelector,而是使用管道映射?的主要内容,如果未能解决你的问题,请参考以下文章

combineLatest不会发出最新值

订阅 combineLatest 中的所有 observables

在 RxJS 5.0 中找不到“combineLatest”

RXSwift ObservableCollection 与 CombineLatest

Rxjs:Observable.combineLatest vs Observable.forkJoin

combineLatest没有被调用