如何将重复的extractData/handleErrors方法移入全局注入服务以遵循DRY原则?
重构重复的HTTP处理方法到全局可注入服务
这确实是个典型的违反DRY原则的场景,把这两个通用的HTTP处理方法抽成全局可注入服务是完美的解决方案,我来一步步帮你实现:
第一步:创建全局HTTP工具服务
我们先新建一个专门处理HTTP通用逻辑的服务(比如命名为HttpHandlerService),把你原来的两个私有方法改成公有方法迁移进来,同时适配Angular和RxJS的最佳实践:
import { Injectable } from '@angular/core'; import { Observable, throwError } from 'rxjs'; import { Response } from '@angular/http'; // 如果你用的是Angular 4+的HttpClient,这里可以替换为对应的Response类型 // 用providedIn: 'root'让服务全局可用,无需在模块中手动声明 @Injectable({ providedIn: 'root' }) export class HttpHandlerService { constructor() { } /** * 从HTTP响应中提取数据 */ public extractData(res: Response) { const body = res.json(); return body || {}; } /** * 统一处理HTTP错误 */ public handleErrors(error: any): Observable<any> { // 注意:RxJS 6+中Observable.throw已废弃,改用throwError return throwError(error.json()); } }
第二步:在业务服务中注入并复用
现在你可以在任何需要的业务服务里注入这个工具服务,替换掉原来重复的方法实现。这里以你的getFoo方法为例:
适配RxJS 6+(Angular 6及以上常用版本)
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map, catchError } from 'rxjs/operators'; import { HttpHandlerService } from './http-handler.service'; import { IFoo } from './foo.interface'; @Injectable({ providedIn: 'root' }) export class FooService { private readonly FooApi = '/api/foo'; constructor( private _http: HttpClient, private httpHandler: HttpHandlerService // 注入全局工具服务 ) { } getFoo(): Observable<IFoo[]> { return this._http.get(this.FooApi) .pipe( // 用箭头函数确保this指向正确,避免上下文丢失 map(res => this.httpHandler.extractData(res)), catchError(err => this.httpHandler.handleErrors(err)) ); } }
适配RxJS 5及以下(旧版本Angular)
如果你的项目还在使用旧版RxJS,写法可以简化为:
getFoo(): Observable<IFoo[]> { return this._http.get(this.FooApi) .map(res => this.httpHandler.extractData(res)) .catch(err => this.httpHandler.handleErrors(err)); }
关键注意点
- 避免上下文丢失:不要直接写
.map(this.httpHandler.extractData),这样会导致extractData方法中的this指向错误,用箭头函数或者.bind(this.httpHandler)来绑定上下文更稳妥。 - 全局注入的优势:通过
providedIn: 'root'声明的服务会被Angular自动处理为单例,全局只实例化一次,性能更优。
内容的提问来源于stack exchange,提问作者Hypenate
相关产品推荐
相关产品推荐

