簡體   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