Fetch的封装

1、安装与配置TypeScript

npm install -g typescript

2、创建Fetch服务

src文件夹中创建一个新的 FetchService.ts 文件。

export class FetchService {
  async get<T>(url: string): Promise<T> {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(response.statusText);
    }
    const data: T = await response.json();
    return data;
  }

  async post<T>(url: string, body: any): Promise<T> {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(body)
    });
    if (!response.ok) {
      throw new Error(response.statusText);
    }
    const data: T = await response.json();
    return data;
  }

  async put<T>(url: string, body: any): Promise<T> {
    const response = await fetch(url, {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(body)
    });
    if (!response.ok) {
      throw new Error(response.statusText);
    }
    const data: T = await response.json();
    return data;
  }

  async delete<T>(url: string): Promise<T> {
    const response = await fetch(url, {
      method: 'DELETE'
    });
    if (!response.ok) {
      throw new Error(response.statusText);
    }
    const data: T = await response.json();
    return data;
  }
}

这样我们就成功地创建了一个FetchService类,它封装了 fetch API的 GETPOSTPUT 和 DELETE 方法。每个方法都返回一个Promise,该Promise解析为一个泛型 T,这意味着你可以指定返回数据的类型。

3、使用FetchService类

import { FetchService } from './FetchService';

const fetchService = new FetchService();

// GET request
const fetchData = async () => {
  try {
    const data = await fetchService.get<{ message: string }>('https://api.example.com/data');
    console.log(data.message);
  } catch (error) {
    console.error('An error occurred:', error);
  }
}

// POST request
const sendData = async () => {
  try {
    const data = await fetchService.post<{ message: string }>('https://api.example.com/data', {
      key: 'value'
    });
    console.log(data.message);
  } catch (error) {
    console.error('An error occurred:', error);
  }
}

// PUT request
const updateData = async () => {
  try {
    const data = await fetchService.put<{ message: string }>('https://api.example.com/data', {
      key: 'new-value'
    });
    console.log(data.message);
  } catch (error) {
    console.error('An error occurred:', error);
  }
}

// DELETE request
const deleteData = async () => {
  try {
    const data = await fetchService.delete<{ message: string }>('https://api.example.com/data');
    console.log(data.message);
  } catch (error) {
    console.error('An error occurred:', error);
  }
}

fetchData();
sendData();
updateData();
deleteData();

4、拦截器实现

在这个版本的 FetchService 中,我们把公共的请求逻辑放到了 _request 方法中。我们把方法(GET、POST、PUT、DELETE),URL和可能的请求体传递给 _request 方法,然后它处理所有的共享逻辑,包括运行拦截器,发送请求,处理响应和解析JSON。

export class FetchService {
  private requestInterceptors: Array<(url: string, options: RequestInit) => void> = [];
  private responseInterceptors: Array<(response: Response) => void> = [];

  async get<T>(url: string): Promise<T> {
    return this._request('GET', url);
  }

  async post<T>(url: string, body: any): Promise<T> {
    return this._request('POST', url, body);
  }

  async put<T>(url: string, body: any): Promise<T> {
    return this._request('PUT', url, body);
  }

  async delete<T>(url: string): Promise<T> {
    return this._request('DELETE', url);
  }

  addRequestInterceptor(interceptor: (url: string, options: RequestInit) => void) {
    this.requestInterceptors.push(interceptor);
  }

  addResponseInterceptor(interceptor: (response: Response) => void) {
    this.responseInterceptors.push(interceptor);
  }

  private async _request<T>(method: string, url: string, body?: any): Promise<T> {
    let options: RequestInit = {
      method: method,
      headers: {
        'Content-Type': 'application/json'
      }
    };
    if (body) {
      options.body = JSON.stringify(body);
    }
    this.runRequestInterceptors(url, options);
    const response = await fetch(url, options);
    this.runResponseInterceptors(response);
    if (!response.ok) {
      throw new Error(response.statusText);
    }
    const data: T = await response.json();
    return data;
  }

  private runRequestInterceptors(url: string, options: RequestInit) {
    this.requestInterceptors.forEach(interceptor => interceptor(url, options));
  }

  private runResponseInterceptors(response: Response) {
    this.responseInterceptors.forEach(interceptor => interceptor(response));
  }
}

使用实例:

const fetchService = new FetchService();

// 添加一个请求拦截器
fetchService.addRequestInterceptor((url, options) => {
  options.headers = {
    ...options.headers,
    'Authorization': 'Bearer ' + localStorage.getItem('token')
  };
});

// 添加一个响应拦截器
fetchService.addResponseInterceptor(response => {
  if (response.status === 401) {
    console.error('Unauthorized!');
  }
});
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值