【问题标题】:Subscribe is deprecated: Use an observer instead of an error callback不推荐使用订阅:使用观察者而不是错误回调
【发布时间】:2019-08-23 14:57:20
【问题描述】:

当我运行 linter 时,它会说:

subscribe is deprecated: Use an observer instead of an error callback

代码(来自带有 angular-cli 的 Angular 7 应用程序):

    this.userService.updateUser(data).pipe(
       tap(() => {bla bla bla})
    ).subscribe(
       this.handleUpdateResponse.bind(this),
       this.handleError.bind(this)
    );

不知道具体应该使用什么以及如何使用...

谢谢!

【问题讨论】:

  • * 所以尝试使用.subscribe({ next: this.handleUpdateResponse.bind(this), error: this.handleError.bind(this) })
  • 我无法使用我的 apiRest 使其工作
  • 可以在这里找到详细的答案jeffryhouser.com/index.cfm/2019/8/27/…

标签: callback rxjs deprecated tslint subscribe


【解决方案1】:

在官网查看详情 https://rxjs.dev/deprecations/subscribe-arguments

请注意下面第二个订阅代码中的 {} 大括号。

import { of } from 'rxjs';

// recommended 
of([1,2,3]).subscribe((v) => console.info(v));
// also recommended
of([1,2,3]).subscribe({
    next: (v) => console.log(v),
    error: (e) => console.error(e),
    complete: () => console.info('complete') 
})

【讨论】:

    【解决方案2】:

    我将我的Angular 项目从TSLint 迁移到ESLint,现在它不再显示警告了!

    我遵循了这些步骤。 (每个步骤结束我也建议提交更改)

    1. 添加 eslint: ng add @angular-eslint/schematics

    2. 将 tslint 转换为 eslint: ng g @angular-eslint/schematics:convert-tslint-to-eslint

    3. 删除tslintcodelyzernpm uninstall -S tslint codelyzer

    4. 如果您想自动修复许多 Lint 问题 ng lint --fix(还会列出未修复的问题)

    5. 在VSCode中卸载TSLint插件,安装ESLint插件并重新加载VSCode。

    6. 确保它更新了包和包锁定文件。还有你项目中的 node_modules。

    7. 如果您在子目录下有tsconfig.json 文件 - 您需要使用tsconfig 文件所在的子目录添加/更新projects-root-directory/.vscode/settings.json

      {
        "eslint.workingDirectories": [
          "sub-directory-where-tsconfig-files-are"
        ]
      }
      

    【讨论】:

    【解决方案3】:

    你应该用 eslint 替换 tslint。

    由于 TSLint 已被弃用,它不支持 RXJS 的 @deprecated 语法。 ESLint 是正确使用的 linter,可以正确地订阅 linting。

    【讨论】:

    【解决方案4】:

    对我来说,这只是我的 VSCode 指向的 typescript 版本。

    从这个GitHub comment获得帮助。

    我相信这是一个打字稿问题。最新版本的打字稿中的某些内容导致此警告显示在 vs 代码中。通过单击 vs code 右下角的 typescript 版本,然后选择 select typescript version 选项,我可以让它消失。我将它设置为我们在 Angular 项目中安装的 node_modules 版本,在我们的例子中恰好是 4.0.7。这导致警告消失。

    【讨论】:

      【解决方案5】:

      我收到警告是因为我将其传递给订阅:

      myObs.subscribe(() => someFunction());
      

      由于返回单个值,与subscribe的函数签名不兼容。

      切换到此会使警告消失(返回 null/void);

      myObs.subscribe(() => {
        someFunction();
      });
      

      【讨论】:

        【解决方案6】:

        如果您有一个类型为 Observable<T> | Observable<T2> 的对象,而不是 Observable<T|T2>,则会出现此错误。

        例如:

            const obs = (new Date().getTime() % 2 == 0) ? of(123) : of('ABC');
        

        编译器不会生成obs 类型为Observable<number | string>

        您可能会感到惊讶,以下内容会给您错误Use an observer instead of a complete callbackExpected 2-3 arguments, but got 1.

        obs.subscribe(value => {
        
        });
        

        这是因为它可能是两种不同类型之一,而编译器不够聪明,无法协调它们。

        您需要更改代码以返回 Observable<number | string> 而不是 Observable<number> | Observable<string>。其细微之处会因您的操作而异。

        【讨论】:

        • 这对我有用,deleteNoteType( NoteTypeId: number ): Observable | HttpErrorResponse> { ... }
        【解决方案7】:

        可能有趣的是,observer 对象还可以(仍然)包含complete() 方法和其他附加属性。示例:

        .subscribe({
            complete: () => { ... }, // completeHandler
            error: () => { ... },    // errorHandler 
            next: () => { ... },     // nextHandler
            someOtherProperty: 42
        });
        

        这样可以更容易地省略某些方法。对于旧签名,必须提供 undefined 并遵守参数的顺序。现在,例如仅提供 next 和 complete 处理程序时,情况就更清楚了。

        【讨论】:

        • 如果使用此表单,如何访问real this
        • 不确定real this 是什么意思。始终可以使用变量,例如 let scopedThis = this 或者您可以使用 bind()
        【解决方案8】:

        subscribe 没有被弃用,只有你正在使用的变体被弃用。将来,subscribe 将只接受一个参数:next 处理程序(一个函数)或观察者对象。

        所以在你的情况下你应该使用:

        .subscribe({
           next: this.handleUpdateResponse.bind(this),
           error: this.handleError.bind(this)
        });
        

        查看这些 GitHub 问题:

        【讨论】:

        • idk... 悬停在 vs 代码中仍然显示不推荐使用该语法(rxjs 6.5.3)
        • 嘿 @YannicHamann this comment 解释了原因。它没有被弃用,他们只是弃用了其中一个重载,现在看起来一切都被弃用了。这主要是一个工具问题。
        • 我认为这个答案不再有效,因为现在 rxjs 6.5.4 中不推荐使用所有订阅方法
        • 是否有一个迁移脚本会自动更新我们所有的subscribe() 方法?我们的项目中有数百个,我无法想象必须手动执行此操作!
        • @AlokRajasukumaran 我们现在应该如何订阅?
        猜你喜欢
        • 2021-06-10
        • 2021-04-20
        • 1970-01-01
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 2021-06-17
        • 1970-01-01
        相关资源
        最近更新 更多