前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《现代Typescript高级教程》实战之封装Fetch

《现代Typescript高级教程》实战之封装Fetch

作者头像
linwu
发布2023-07-31 13:27:38
5740
发布2023-07-31 13:27:38
举报
文章被收录于专栏:编程时光编程时光

theme: smartblue

现代JavaScript高级小册

深入浅出Dart

现代TypeScript高级小册

1. 安装与配置TypeScript

首先,你的电脑上安装TypeScript。在命令行中输入以下命令:

代码语言:javascript
复制
npm install -g typescript

在你的项目根目录中,生成一个 tsconfig.json 文件来配置TypeScript的编译选项。在命令行中输入以下命令:

代码语言:javascript
复制
tsc --init

编辑 tsconfig.json 文件。这个文件配置了TypeScript的编译选项。确保以下设置已经开启:

代码语言:javascript
复制
{
  "compilerOptions": {
    "target": "ES2015",
    "module": "commonjs",
    "strict": true
  }
}

2. 创建Fetch服务

src文件夹中创建一个新的 FetchService.ts 文件。我们将在这个文件中封装fetch API: 当然,下面我们会将putdelete方法也添加到我们的FetchService中:

代码语言:javascript
复制
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的 GET, POST, PUTDELETE 方法。每个方法都返回一个Promise,该Promise解析为一个泛型 T,这意味着你可以指定返回数据的类型。

3. 使用FetchService类

代码语言:javascript
复制
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();

以上代码首先导入了我们创建的 FetchService 类,并实例化了一个新的 fetchService 对象。然后,我们定义了四个异步函数,每个函数都执行一个网络请求,并在请求成功时打印出返回数据中的 message 字段。这四个函数分别对应 GET, POST, PUTDELETE 请求。

我们使用了 <{ message: string }> 来指定返回数据的类型,这样我们就可以得到TypeScript的类型检查和自动补全功能。如果你的数据类型更复杂,你可以定义一个接口来描述它,然后在这里使用那个接口。

如果请求失败,我们在 catch 块中捕获错误并打印错误消息。如果服务器返回的HTTP状态码不是200-299,fetch API会认为请求成功,不会抛出错误。因此,我们在 FetchService 类的每个方法中都检查了 response.ok 属性,如果请求未成功,我们抛出一个包含状态文本的错误。

4.拦截器实现

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

代码语言:javascript
复制
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));
  }
}

示例:

代码语言:javascript
复制
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!');
  }
});

总结

这是一个基础的实现,其它可以根据你的需求来进行修改或扩展

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • theme: smartblue
    • 1. 安装与配置TypeScript
      • 2. 创建Fetch服务
        • 3. 使用FetchService类
          • 4.拦截器实现
          • 总结
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档