【问题标题】:Rxjs: take(1) usageRxjs: take(1) 用法
【发布时间】:2017-09-22 04:24:56
【问题描述】:

我看过一个关于rxjs的教程是这样的。

我的问题是:
1)take(1)在这里有什么用?我在网上看到很多解释,但我真的不明白。另外,我看不出在这段代码中使用take(1) 有什么好处。并且作者确实在 REST api 相关服务中的每个返回函数上都使用了take(1)

2) 订阅后作者没有退订。是不是因为作者使用take(1)所以不需要手动取消订阅?

3) 如果我想实现 catch 功能怎么办。我应该在拍摄前还是拍摄后实施。

getProfile() { // this is a call to REST API
    return this.service.getProfile()
            .map(res => res.json())
            .take(1)
    }
}

this.data.getProfile().subscribe(profile => {
    this.userProfile = profile;
});

【问题讨论】:

    标签: angular ionic-framework ionic2 rxjs


    【解决方案1】:

    作者订阅后没有退订。是不是因为 作者使用 take(1) 因此不需要手动取消订阅?

    是的,这很可能是作者使用take(1) 运算符的原因。你可以阅读更多关于 take 操作员here。它的工作是将一个值传递给可观察对象,然后从源中取消订阅。但根据服务的不同,可能不需要。

    例如,在 Angular 中,HttpClient 服务在发送最终的 HttpResponse 事件值后自行完成流,因此您无需使用 take 或显式取消订阅。 Here is the sources:

    @Injectable()
    export class HttpXhrBackend implements HttpBackend {
      ...
      handle(req: HttpRequest<any>): Observable<HttpEvent<any>> {
        ...
        // Everything happens on Observable subscription.
        return new Observable((observer: Observer<HttpEvent<any>>) => {
          ...
          // First up is the load event, which represents a response being fully available.
          const onLoad = () => {
            ...
            if (ok) {
              // A successful response is delivered on the event stream.
              observer.next(new HttpResponse({
                body,
                headers,
                status,
                statusText,
                url: url || undefined,
              }));
              // The full body has been received and delivered, no further events
              // are possible. This request is complete.
              observer.complete();   <---------------------------------
            }
    

    如果我想实现 catch 功能怎么办。我应该在拍摄前还是拍摄后实施。

    你可以在take之后实现它,因为take也会传递错误。

    const stream = Observable.create((observer) => {
      observer.error(new Error());
    }).take(1).catch(() => {
      return Observable.of(`An error occurred`);
    }).subscribe((v) => {
      console.log(v);  // An error occurred
    })
    

    【讨论】:

    • 感谢您的澄清。是否有任何文档说明即使没有 take(1) 的角度 HttpClient 服务来支持您的声明,也无需显式调用取消订阅?
    • 有关文档,请查看(请原谅双关语)Observable Contract。这是确定的。 take 完成了 observable,完成后看到所有订阅者自动取消订阅。
    • @stackdisplay,更新了答案。最好的文档是来源:)。查看 angularindepth.com 出版物,其中所有文章都以该座右铭发表
    • @AngularInDepth.com。嗨,我看过很多教程,建议使用 async 管道自动取消订阅,以角度 http 请求为例。但是,根据您的说明,我认为可以忽略 async 管道以获得更简洁的代码。或者仍然使用async 管道有什么好处吗?
    • @stackdisplay,你能再创建一个问题吗?这将对社区有益,其他人将能够看到并为答案做出贡献
    猜你喜欢
    • 2019-10-14
    • 2019-11-15
    • 1970-01-01
    • 2020-10-25
    • 2020-11-16
    • 1970-01-01
    • 2019-06-05
    • 2018-04-09
    • 2016-10-03
    相关资源
    最近更新 更多