繁体   English   中英

使用RxJS从订阅中返回Observable

[英]Return a Observable from a Subscription with RxJS

我目前有一项服务,它向API发送HTTP请求以获取数据。 我想从服务中对observable做一些逻辑,但我仍然想在我的Component中订阅Observable,这样我就可以将任何错误返回给Component和用户。

目前我这样做:

// service.ts
getData(): Observable<any> {
    return this.http.get(url).pipe(catchError(this.handleError)
}

// component.ts
ngOnInit() {
    this.service.getData().subscribe(res => {
        // Do my logic that belong to the service.ts
        // ...

        // Do my logic that belongs in the component.ts
        // ...
    }, err => this.errors = err)
}

我想要做的是重构这个,以便我在getData()方法中处理与订阅和service.ts相关的逻辑,然后返回一个带有HTTP响应和任何错误的Observable到Component,这样我就可以了可以继续在那里做事。

这样做的模式是什么?

我觉得发布的模式和解决方案的多个是“丑陋的”或者不遵循Observable模式(就像做回调一样)。

我想出的最干净,最“RxJS”的解决方案是将服务方法包装在第二个Observable工厂方法中。

所以以下内容:

// service.ts
getData(): Observable<any> {
    return Observable.create((observer: Observer) => {
        this.http.get(url)
          .pipe(catchError(this.handleError)
          .subscribe(res => {
              // Do my service.ts logic.
              // ...
              observer.next(res)
              observer.complete()
          }, err => observer.error(err))
    })
}

// component.ts
ngOnInit() {
    this.service.getData().subscribe(res => {
        // Do my component logic.
        // ...
    }, err => this.errors = err)
}

使用map

// service.ts:

import { catchError, map } from 'rxjs/operators';

getData(): Observable<any> {
    return this.http.get(url).pipe(
        map(res => {
            /* Your processing here */
            return res;
        }),
        catchError(this.handleError)
    )
}

试试这种方式

service.ts

getData(): Observable<any> {
  return this.http.get(url).map(res=> <any>(res['_body']));
}

component.ts

this.service.getData().subscribe(response=>{
            var res1 = JSON.stringify(response);
            var res2 = JSON.parse(res1);
            var res3 = JSON.parse(res2);
});  //parse response based on your response type 

选项1

如果您在组件中订阅Observable ,则只有组件将具有该订阅,并且必须将其传递回service

选项2

使用此模式。

service.ts

    getData(doer: Function) {
        let subscriptions = Observable.of({ data: 'response', isError: false })// request
            .catch(error => Observable.of({ data: error, isError: true })) //handle error
            .do(data => doer(data))
            .subscribe();
        this.handleSubscription(subscriptions); //subscription handling in service
    }

component.ts

    ngOnInit() {
        this.getData(response => {
            if (response.isError) {
                ///
            } else {
                let data = response.data;
                // Process
            }
        })
    }

您可以删除this ,并使用map 在订阅错误中,您可以获得错误事件。

如果您使用HttpClient,只需使用get!

注意:所有的答案都是针对<= Angular 4.在Angular 5中,你不再需要map() ,所以就这样做吧。 只需返回this.http.get()因为它返回一个Observable,您可以在其中订阅。

此外,请注意您必须导入HttpClient而不是Http

您可以直接在http.get方法返回的Observable上使用“map”和“catch”函数。

import { catchError, map } from 'rxjs/operators';

getData(): Observable<any> {
    return this.http.get(url)
        .map(res => {
            /* Your processing here */
            return res;
        })
        .catch(this.handleError);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM