【问题标题】:What is the actual difference between pipe and subscribe?管道和订阅之间的实际区别是什么?
【发布时间】:2020-02-16 15:38:22
【问题描述】:

我正在开发一个 HttpInterceptor。为了开发这个拦截器,我正在创建一个服务类,如下所示:

import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';

export class InterceptorClass implements HttpInterceptor{
    intercept(req: HttpRequest<any>, next: HttpHandler){
        debugger
        req= req.clone({
            headers: req.headers.append('currentPlace','New Delhi')
        });
       return next.handle(req); //Doubt in this line
    }
}

现在我的疑问是,每当我在next.handle(req) 之后使用.pipe() 方法时,它都不会显示任何错误。代码如下:

import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';

export class InterceptorClass implements HttpInterceptor{
    intercept(req: HttpRequest<any>, next: HttpHandler){
        debugger
        req= req.clone({
            headers: req.headers.append('currentPlace','New Delhi')
        });
        return next.handle(req).pipe(tap(()=>{

       }));
    }
}

但是每当我在next.handle() 之后使用.subscribe() 时,都会出错。 代码如下:

import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';
import { map, tap } from 'rxjs/operators';

export class InterceptorClass implements HttpInterceptor{
    intercept(req: HttpRequest<any>, next: HttpHandler){
        debugger
        req= req.clone({
            headers: req.headers.append('currentPlace','New Delhi')
        });
       return next.handle(req).subscribe((data)=>{

       });
    }
}

我们订阅时得到的错误是:

      Type '(req: HttpRequest<any>, next: HttpHandler) => Subscription' is not assignable to type '(req: HttpRequest<any>, next:
HttpHandler) => Observable<HttpEvent<any>>'.
        Type 'Subscription' is missing the following properties from type 'Observable<HttpEvent<any>>': _isScalar, source, operator, lift, and 6 more.

为什么当我们 subscribe()next.handle() 时会出错,因为我读到 next.handle() 返回一个 Observable,因此我们可以订阅它?

【问题讨论】:

  • intercept() 方法必须返回一个 Observable。 pipe() 将一个 Observable 转换为另一个 Observable,所以这是正确的。 subscribe()... 订阅 Observable 并返回 Subscription,而不是 Observable,所以这是不正确的。
  • 为什么你认为他们是一样的?仅仅因为您可以订阅某些东西并不意味着这总是正确的做法。

标签: angular typescript http angular-http-interceptors


【解决方案1】:

订阅时,结果会在函数内返回

pipe() 返回一个你可以订阅的 observable pipe() 允许您处理原始的 observable,这样当您订阅它时,您会得到与 observable 最初发出的不同的值

把它想象成一个管道,pipe() 在值到达您订阅的值之前进行某种处理

【讨论】:

  • 感谢您的精彩解释。您能否解释一下为什么在“pipe()”方法中使用“map”运算符而不是“tap”运算符时会出错?
【解决方案2】:

pipe() 命令用于通过一系列不同的处理命令(称为操作符)运行 Observable 的结果。最终返回仍将是ObservableThis is a good explanation of what pipeable operators are。我的简化版本是 pipeable operator 是一个用于处理 Observable 结果的函数。

subscribe() 命令用于获取 Observable 的结果,它返回一个Subscription

订阅与 Observable 不同,这就是它们不能互换使用的原因。值得注意的是,如果没有subscribe(),可管道操作符将永远不会对从 Observable 返回的结果执行。

【讨论】:

  • 感谢您的精彩解释。您能否解释一下为什么在“pipe()”方法中使用“map”运算符而不是“tap”运算符时会出错?
  • 没有看到代码我不确定。确保已导入地图运算符。确保有东西被退回。
  • 地图算子已导入。我认为“next.handle()”不允许对它返回的 observable 进行任何操作,这就是为什么每当我使用 map 运算符时它都会出错。
  • @johnny 不知道该链接之前的内容,但我认为这是更新后的文档,其中包含有关可管道操作符的信息:github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/…
猜你喜欢
  • 1970-01-01
  • 2023-03-08
  • 2021-06-12
  • 1970-01-01
  • 2010-10-22
  • 1970-01-01
  • 2012-05-08
  • 2011-03-06
  • 1970-01-01
相关资源
最近更新 更多