订阅已过时:使用观察者代替错误回调。

328

当我运行linter时,它会报告:


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

这个 Angular 应用程序的代码来自此处

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

不知道应该使用什么和如何使用...。谢谢!

9
尝试使用.subscribe({ next: this.handleUpdateResponse.bind(this), error: this.handleError.bind(this) }) - kos
我无法通过我的apiRest使其运行。 - Javier
6
详细答案可以在这里找到:https://www.jeffryhouser.com/index.cfm/2019/8/27/What-is-the-new-syntax-for-subscribing-to-Observables - Mohd Jawwad Hussain
10个回答

465

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

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

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

请查看这些GitHub问题:


57
不确定……在 VS Code 中悬停仍显示使用了过时的语法(rxjs 6.5.3)。 - Yannic Hamann
22
嘿@YannicHamann,这条评论解释了原因。它并没有被废弃,只是其中一种重载已被弃用,现在看起来好像一切都被弃用了。这主要是一个工具问题。 - Dean
5
我认为这个答案已经不再有效,因为在rxjs 6.5.4中,所有的订阅方法都已经被弃用。 - Alok Rajasukumaran
6
жңүжІЎжңүдёҖд»ҪиҝҒ移и„ҡжң¬еҸҜд»ҘиҮӘеҠЁжӣҙж–°жҲ‘们项зӣ®дёӯзҡ„жүҖжңүsubscribe()ж–№жі•пјҹжҲ‘们项зӣ®дёӯжңүж•°зҷҫдёӘиҝҷж ·зҡ„ж–№жі•пјҢжҲ‘ж— жі•жғіиұЎжүӢеҠЁе®ҢжҲҗиҝҷйЎ№е·ҘдҪңпјҒ - AsGoodAsItGets
6
@AlokRajasukumaran,我们现在应该如何订阅? - Leonardo Rick
显示剩余4条评论

159

值得一提的是,observer对象仍然可以包含complete()方法和其他附加属性。例如:

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

这样做可以更轻松地省略某些方法。在旧的签名中,需要提供undefined并坚持参数顺序。现在,如果仅提供下一个和完成处理程序,情况就会清晰得多。


如果使用此表单,如何访问“real this”? - Sebi2020
1
不确定你所说的“real this”是什么意思。可以随时使用变量,例如 let scopedThis = this 或者使用 bind() 方法。 - magikMaker
正是我所需要的!当将一个observer对象传递到subscribe()中时,如果您不想指定next()error()回调函数,则无需显式地输入undefined作为缺失参数。 - Theta

55

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

VSCode status bar

TypeScript version selector

Select local TypeScript version

我从这个GitHub评论得到了帮助。

我认为这是一个typescript问题。最新版本的typescript中的某些内容会导致在vs code中显示此警告。我通过单击vs code右下角的typescript版本,然后选择选择typescript版本选项来使其消失。我将其设置为我们在angular项目中安装的node_modules版本,我们的情况下是4.0.7。这样就可以消除警告。


30

请在官方网站查看详情: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') 
})

23
您可能会遇到这个错误,如果您的对象类型为 Observable<T> | Observable<T2>,而不是 Observable<T|T2>
例如:
    const obs = (new Date().getTime() % 2 == 0) ? of(123) : of('ABC');

编译器不会将类型为 Observable 的 obs 进行处理。以下代码可能会让您惊讶,它会报错:使用观察者而不是完整回调函数,并且期望 2-3 个参数,但只传了一个参数。
obs.subscribe(value => {

});

这是因为它可以是两种不同的类型之一,而编译器不能够智能地协调它们。

您需要更改代码,以返回Observable<number | string>,而不是Observable<number> | Observable<string>。这个细节会根据您所做的事情而有所不同。


这对我有用,deleteNoteType(NoteTypeId:number):Observable <HttpResponse <undefined> | HttpErrorResponse> {...} - Phil Huhn

17
新的RxJS使用方式非常简单:
以前的版本:
this.activatedRoute.queryParams.subscribe(queryParams => {
console.log("queryParams, queryParams)

}, error => {
})

新版本:

  this.activatedRoute.queryParams.subscribe(
  {
    next: (queryParams) => {
      console.log('queryParams', queryParams);
    },

    error: (err: any) => { },
    complete: () => { }
  }
);

4

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

我按照以下步骤进行操作。(建议在每个步骤结束时提交更改)

  1. Add eslint: ng add @angular-eslint/schematics

  2. Convert tslint to eslint: ng g @angular-eslint/schematics:convert-tslint-to-eslint

  3. Remove tslint and codelyzer: npm uninstall -S tslint codelyzer

  4. If you like to auto fix many of the Lint issues ng lint --fix (It will also list the not fixed issues)

  5. In VSCode uninstall the TSLint plugin, install ESLint plugin and Reload the VSCode.

  6. Make sure it updated the package and package-lock files. Also the node_modules in your project.

  7. If you have the tsconfig.json files under sub directory - you need to add/update the projects-root-directory/.vscode/settings.json with the sub directory where the tsconfig files are!

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

1
在 VS Code 官方页面上,有关从 TSLint 迁移到 ESNint 的更多详细信息,请参见以下链接: https://code.visualstudio.com/api/advanced-topics/tslint-eslint-migration - viking

2
我收到了警告,是因为我将“this”传递给了subscribe函数:
myObs.subscribe(() => someFunction());

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

更改为这个后,警告消失了(返回null / void);

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

1
你应该用eslint代替tslint。
由于TSLint已被弃用,它不支持RXJS的@deprecated语法。ESLint是正确的代码检查工具,可以正确地进行subscribe检查。

11
我认为这个解决方案不好,因为忽视问题并不能解决它。 - Remy
3
在这种情况下,问题并不是忽略它,因为似乎只是一个 TSLint 的 bug:https://dev59.com/questions/g1EG5IYBdhLWcg3wZsg4#66605060 ... 但更重要的是要知道 TSLint 已经被弃用,推荐使用 ESLint:https://dev59.com/questions/g1EG5IYBdhLWcg3wZsg4#66933996。 - Rancid
这并不是忽视,而是排除了一个错误的误解。 - Caveman
这不是忽视,而是排除了一个错误的误解。 - undefined

1
新的订阅语法为:
 this.fetch().subscribe({
        next: (account: Account) => {
            console.log(account);
            console.log("Your code ...");
        },

        error: (e) => {
            console.error(e);
        },

        complete() {
          console.log("is completed");
        },
});

完整回调的目的是什么?它是否与 Promise 的 finally 方法有些相似? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接