如何将相同的方法链接到多个可观察对象?

时间:2018-06-21 22:31:39

标签: typescript rxjs observable

假设我通过以下方法提供以下服务,这些方法可以进行一些API调用:

class MyService {
    constructor(protected http: HttpClient) { } 

    getItems() {
        return this.http
            .get(`/api/items`)
            .catch(this.handleError)
            .finally(() => { return; });
    }

    getItem(id: string) {
        return this.http
            .get(`/api/items/${id}`)
            .catch(this.handleError)
            .finally(() => { return; });
    }

    addItem(item: Object) {
        return this.http
            .post(`/api/items`, JSON.stringify(item))
            .catch(this.handleError)
            .finally(() => { return; });
    }

    editItem(id: string, item: Object) {
        return this.http
            .put(`/api/items/${id}`, JSON.stringify(item))
            .catch(this.handleError)
            .finally(() => { return; });
    }

    private handleError(err: any) {
        console.error(err);
    }
}

注意如何在多个位置重复相同的.catch(...).finally(...)行代码。我想将这些方法链接在一起以减少代码重复。

这是我到目前为止所做的,但是它破坏了链接的可读性。在我看来,可能还有另一种方法可以保持链接的顺序。关于可观察性,我还是一个新手。

class MyService {
    constructor(protected http: HttpClient) { } 

    getItems() {
        return this.applyExtras(this.http.get(`/api/items`));
    }

    getItem(id: string) {
        return this.applyExtras(this.http.get(`/api/items/${id}`));
    }

    addItem(item: Object) {
        return this.applyExtras(this.http.post(`/api/items`, JSON.stringify(item)));
    }

    editItem(id: string, item: Object) {
        return this.applyExtras(this.http.put(`/api/items/${id}`, JSON.stringify(item)));
    }

    private applyExtras(obs: Observable<any>): Observable<any> {
        return obs
            .catch(this.handleError)
            .finally(() => { return; });
    }

    private handleError(err: any) {
        console.error(err);
    }
}

1 个答案:

答案 0 :(得分:1)

如果至少使用RxJS 5.5.0,则可以使用pipeable运算符来共享通用运算符的管道。

class MyService {
    constructor(protected http: HttpClient) { } 

    private withErrorHandler: any = [
      catchError(this.handleError),
      finalize(() => {})
    ]

    getItems() {
        return this.http
            .get(`/api/items`)
            .pipe(...withErrorHandler)
    }
}

或者,如果您不想使用可传递的语法,或者您使用的是RxJS的早期版本,则可以改用let

private withErrorHandler: any = (source) => 
  source.catch(this.handleError).finally(() => {})

getItems() {
  return this.http
     .get(`/api/items`)
     .let(withErrorHandler)
}