angular12封装好的一个httpService类

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class HttpService {
  private apiUrl = 'http://localhost:3000/api'; // API URL
  httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' })
  };

  constructor(private http: HttpClient) { }

  // GET method
  get(endpoint: string): Observable<any> {
    const url = `${this.apiUrl}/${endpoint}`;
    return this.http.get(url, this.httpOptions).pipe(
      tap(_ => console.log(`fetched ${endpoint}`)),
      catchError(this.handleError)
    );
  }

  // POST method
  post(endpoint: string, data: any): Observable<any> {
    const url = `${this.apiUrl}/${endpoint}`;
    return this.http.post(url, data, this.httpOptions).pipe(
      tap(_ => console.log(`posted ${endpoint}`)),
      catchError(this.handleError)
    );
  }

  // PUT method
  put(endpoint: string, data: any): Observable<any> {
    const url = `${this.apiUrl}/${endpoint}`;
    return this.http.put(url, data, this.httpOptions).pipe(
      tap(_ => console.log(`updated ${endpoint}`)),
      catchError(this.handleError)
    );
  }

  // DELETE method
  delete(endpoint: string): Observable<any> {
    const url = `${this.apiUrl}/${endpoint}`;
    return this.http.delete(url, this.httpOptions).pipe(
      tap(_ => console.log(`deleted ${endpoint}`)),
      catchError(this.handleError)
    );
  }

  // Error handling
  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    // return an observable with a user-facing error message
    return throwError('Something bad happened; please try again later.');
  };
}

tap()是一个RxJS操作符,用于在Observable的数据流中添加一个副作用,而不改变数据流本身。它类似于subscribe(),但不会订阅Observable并触发数据流,只是允许你执行一些副作用操作,例如调试、记录、修改状态等。

tap()的语法如下:

tap(
  next?: (value: T) => void,
  error?: (error: any) => void,
  complete?: () => void
): Observable<T>

它接收三个可选参数,分别为:

  • next:一个函数,当Observable发出一个值时调用。它接收Observable发出的值,并执行一些操作,但不会改变值或数据流。
  • error:一个函数,当Observable发出一个错误时调用。它接收Observable发出的错误,并执行一些操作,但不会改变错误或数据流。
  • complete:一个函数,当Observable完成时调用。它不接收任何参数,并执行一些操作,但不会改变数据流。

tap()操作符通常用于调试和日志记录。例如,我们可以使用tap()记录HTTP请求的状态,如下所示:

get(endpoint: string): Observable<any> {
  const url = `${this.apiUrl}/${endpoint}`;
  return this.http.get(url, this.httpOptions).pipe(
    tap(
      _ => console.log(`fetched ${endpoint}`),
      error => console.error(`error occurred: ${error}`)
    ),
    catchError(this.handleError)
  );
}

在这个示例中,当get()方法从服务器获取数据时,它会记录所请求的端点并将其打印到控制台。如果请求失败,则会记录错误信息。

除了调试和记录之外,tap()操作符还可以用于修改状态,例如在HTTP请求之前或之后修改一些变量或状态。

需要注意的是,tap()操作符应该只用于添加副作用,而不应该用于改变Observable的数据流。如果你需要改变数据流本身,应该使用其他操作符,例如map()filter()等。

以下是一个使用tap()操作符来修改状态的示例代码:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { tap, catchError } from 'rxjs/operators';
import { Observable, throwError } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class UserService {
  isLoggedIn = false;

  constructor(private http: HttpClient) {}

  login(username: string, password: string): Observable<any> {
    return this.http.post('/api/login', { username, password }).pipe(
      tap(
        response => {
          this.isLoggedIn = true;
          localStorage.setItem('token', response.token);
        },
        error => {
          this.isLoggedIn = false;
          console.error(`error occurred: ${error}`);
        }
      ),
      catchError(this.handleError)
    );
  }

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

throwError()方法返回一个Observable对象,该对象的error回调函数可以捕获抛出的错误,并将错误对象传递给下游的subscribe()函数中的error回调函数进行处理。

httpService中,我们可以使用throwError()方法来处理HTTP请求过程中可能出现的错误,并将错误传递给下游的subscribe()函数中的error回调函数进行处理。例如,在httpService中的get()方法中可以这样处理HTTP请求的错误:

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class HttpService {
  constructor(private http: HttpClient) {}

  get(url: string): Observable<any> {
    return this.http.get(url).pipe(
      catchError((error: HttpErrorResponse) => {
        return throwError(error);
      })
    );
  }
}

在这个例子中,get()方法使用catchError()操作符来捕获可能出现的错误,并将错误传递给throwError()方法。throwError()方法返回一个Observable对象,该对象的error回调函数可以捕获抛出的错误,并将错误对象传递给下游的subscribe()函数中的error回调函数进行处理。

在使用httpService的组件中,可以这样接收并处理由throwError()方法抛出的错误:

import { Component } from '@angular/core';
import { HttpService } from './http.service';
import { HttpErrorResponse } from '@angular/common/http';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.css']
})
export class MyComponent {
  constructor(private httpService: HttpService) {}

  getData() {
    this.httpService.get('https://jsonplaceholder.typicode.com/posts/1').subscribe(
      data => {
        console.log(data);
      },
      (error: HttpErrorResponse) => {
        console.log(error);
      }
    );
  }
}

在这个例子中,当get()方法执行HTTP请求出现错误时,subscribe()函数的第二个参数会被调用,并将错误对象传递给该函数。在这里,我们只是简单地将错误对象打印到控制台,但你可以根据实际情况执行其他操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值