添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
·  阅读 「超详细React项目搭建教程七」封装 Fetch 请求

fetch API 是原生 JavaScript 提供的一个概念,主要用来与 Web 服务器进行交互。 我们如何在 async await 中使用 fetch 呢? 以及如何将它与 TypeScript 结合在一起使用呢? 让我们开始探索吧……

创建一个简单的请求

ES 最新特新已支持在 顶层 await ,因此,我们只需要把 await 关键字放在 fetch 函数前面即可

const response = await fetch("https://jsonplaceholder.typicode.com/todos");

为了获得响应的内容,我们需要调用 response 的json 方法

const body = await response.json();

注意: 我们使用了await关键字,因为response.json()是异步的。

创建一个工具函数

我们创建一个可以被调用的请求工具函数-http,该函数将上面两行代码结合起来并返回响应内容

export async function http(request: RequestInfo): Promise<any> {
  const response = await fetch(request);
  const body = await response.json();
  return body;
// example consuming code
const data = await http("https://jsonplaceholder.typicode.com/todos");

很棒! 我们通过调用请求工具-http函数,一行代码就实现了数据的请求和响应!

定义响应数据的类型

在前面的例子中,我们将响应数据的类型设置为Promise<any>,接下来我们把此类型再精确一下

export async function http<T>(request: RequestInfo): Promise<T> {
  const response = await fetch(request);
  const body = await response.json();
  return body;
// example consuming code
interface Todo {
  userId: number;
  id: number;
  title: string;
  completed: boolean;
const data = await http<Todo[]>("https://jsonplaceholder.typicode.com/todos");

现在,我们的http函数接收一个泛型参数作为响应数据的类型.

泛型就可以实现我们的场景: 一个函数可以支持多种数据类型 并且不预先确定数据类型,具体的类型在使用的时候才能确认

在上面的代码中,我们的data这个数据的真实类型其实Todo[]

较完善的响应类型定义

interface HttpResponse<T> extends Response {
  parsedBody?: T;
export async function http<T>(request: RequestInfo): Promise<HttpResponse<T>> {
  const response: HttpResponse<T> = await fetch(request);
  response.parsedBody = await response.json();
  return response;
// example consuming code
const response = await http<Todo[]>(
  "https://jsonplaceholder.typicode.com/todos",

因此,我们使用extends继承了 TS 中Response类型来解析的响应内容。 在整个响应被返回之前,我们在响应上设置parsedBody属性。 现在,我们上面的代码中获得了完整的响应。

捕获 http 工具中的错误

现在,让我们优化http函数来处理 HTTP 请求中发生错误的情况。 如果请求失败,我们可以使用response对象中的ok属性进行判断

export async function http<T>(request: RequestInfo): Promise<HttpResponse<T>> {
  const response: HttpResponse<T> = await fetch(request);
  try {
    // 如果没有响应内容,这里可能会报错
    response.parsedBody = await response.json();
  } catch (ex) {}
  if (!response.ok) {
    throw new Error(response.statusText);
  return response;
// 示例
let response: HttpResponse<Todo[]>;
try {
  response = await http<Todo[]>("https://jsonplaceholder.typicode.com/todosX");
  console.log("response", response);
} catch (response) {
  console.log("Error", response);

使用try ... catch 将错误 ❎ 抛出到外部

HTTP 中的请求方法封装

通过调用http函数,我们可以如何使用除GET之外的 HTTP 方法,如下所示

const response = await http<{
  id: number;
  new Request("https://jsonplaceholder.typicode.com/posts", {
    method: "post",
    body: JSON.stringify({
      title: "my post",
      body: "some content",

我们为期望的响应正文类型传递了一个内联类型{id:number},即,我们希望将新帖子的 ID 返回给我们。

并且注意,我们必须使用JSON.stringify将 post 对象转换为字符串。

比较麻烦是不是,但我们可以通过为不同的 HTTP 方法提供特定的功能,让使用者的的工作变得更轻松:

export async function get<T>(
  path: string,
  args: RequestInit = { method: "get" }
): Promise<HttpResponse<T>> {
  return await http<T>(new Request(path, args));
export async function post<T>(
  path: string,
  body: any,
  args: RequestInit = { method: "post", body: JSON.stringify(body) }
): Promise<HttpResponse<T>>  {
  return await http<T>(new Request(path, args));
export async function put<T>(
  path: string,
  body: any,
  args: RequestInit = { method: "put", body: JSON.stringify(body) }
): Promise<HttpResponse<T>> {
  return await http<T>(new Request(path, args));
// example consuming code
const response = await post<{ id: number }>(
  "https://jsonplaceholder.typicode.com/posts",
  { title: "my post", body: "some content" }

因此,这些函数调用基本的 http 函数,但设置了正确的 HTTP 方法并为我们序列化了请求体。

现在,使用 HTTP 请求更加简单了!

借助一些不错的包装,我们可以轻松地将fetch,await,async,TypeScript 一起使用。 我们还对 HTTP 请求错误进行了抛出,这可以说是 HTTP 库的一种较常见的行为。 最后封装了针对 HTTP 请求方法的函数,使与 Web 服务进行交互变得非常容易。

参考文档:

  • www.carlrippon.com/fetch-with-…
  • 当然!还有许多请求过程中的问题需要判断和处!咱们后续再更新,敬请期待!

    你觉得上面的fetch请求工具还需要哪些优化呢?欢迎在评论区留下的你的见解!

    觉得有收获的朋友欢迎点赞关注一波!

    react 构建系列

  • 企业级前端开发规范如何搭建 🛠
  • 「React Build」之集成 Webpack5/React17
  • 「React Build」之集成 CSS/Less/Sass/Antd
  • 「React Build」之集成图片/字体
  • 「React Build」之集成 Redux/Typescript
  • 「React Build」之使用 Redux-thunk 实现 Redux 异步操作
  • 「React Build」之集成 React-Router/Antd Menu 实现路由权限
  • 分类:
    前端
    标签: