Skip to content

内置功能

自定义请求别名
new

sluggard-http 支持自定义请求别名

  • 可设置新的请求别名以抽离 请求体 / 响应体 进行统一修改的场景
  • 亦可以对原始请求别名(GET/POST/PUT/DELETE...)进行重构

类型

ts
interface MethodAlias {
  [aliasName: string]: {
    axiosMethod: AxiosMethodsName
    handle: MethodAliasHandle
  }
}

type MethodAliasHandle = (...params: any[]) => any[]

示例 - 修改请求体的别名

ts
import type { RequestConfig } from 'sluggard-http'
import { Http } from 'sluggard-http'

const methodAlias = {
  // 👇 要新建的别名名称
  download: {
    // 此别名实际上调用的 axios 方法
    axiosMethod: 'post',
    // 别名处理函数
    handle: (url: string, data: any, config: RequestConfig) => {
      // 为请求体添加 responseType 参数
      return [url, data, { ...config, responseType: 'blob' }]
    },
  },
} as const // 此处获取字面量类型,有助于ts类型推导

// 创建 http 实例 传入 typeof methodAlias 泛型,使 http.download() 能够自行推导类型
export const http = Http.create<typeof methodAlias>(
  {
    baseURL: '...',
    timeout: 1000,
    headers: {'Authorization': '...'}
  }, 
  {
    methodAlias, 
    life: { ... },
  }
)
  • handle 详解
    • 接受任意参数, handle 的参数即为你所新增别名的参数
    • 返回一个数组, 该数组将作为 实际上调用的 axios 方法 的参数传入

效果

  • 上述代码将新增一个download 别名并挂载到 http 实例上
  • 通过 http.download() 即可调用,调用时实际等于执行了以下伪代码
ts
http.download(url, data, config){
  // 调用你定义的 handle 函数, 为请求体添加 responseType 参数
  const [url, data, config] = handle(url, data, config)
  // 返回实际调用的 axios 方法
  return http.post(url, data, config)
}

示例 - 修改响应体的别名

ts
import type { MethodAlias, RequestConfig } from 'sluggard-http'
import { Http } from 'sluggard-http'

const methodAlias = {
  data: {
    axiosMethod: 'post',
    handle: (url: string, data: any, config: RequestConfig) => {
      // 在 RequestConfig 中添加一个 postType 标识符, 用于在响应拦截器中捕获此请求
      return [url, data, { ...config, postType: "postData" }]
    },
  },
} as const

// 创建 http 实例
...
ts
// 配合响应拦截器使用
http.interceptorsResponseUse((response) => {
  // ...
  if (
    response.config.postType === 'postData' // 捕获由 data 别名发起的请求
    && response.data.code === 200 // 判断 code 值
  ){
    return response.data.data // 直接返回 data 字段承载的数据体
  }
  // ...
  return response
})

效果

  • 上述代码将新增一个data 别名并挂载到 http 实例上
  • 通过 http.data() 即可调用
  • http.data() 请求成功且响应体的 code 字段为 200 时, 直接返回响应体的 data 字段数据

示例 - 重构原有请求别名

ts
import type { MethodAlias, RequestConfig } from 'sluggard-http'
import { Http } from 'sluggard-http'
import { clearTrim } from "utils" // 引入一个你定义的用于去除字符串头尾空格的工具

const methodAlias = {
  // 👇 将重构原别名
  post: {
    axiosMethod: 'post',
    handle: (url: string, data: any, config: RequestConfig) => {
      // 调用去除空格工具函数
      clearTrim(config)
      return [url, data, config]
    },
  },
} as const

// 创建 http 实例
...

效果

  • 上述代码将修改 http 实例原有的 post 别名
  • 调用 http.post() 时会自动去除请求体中字符串字段数据的头尾空格

请求控制
new

提供多种对进行中请求进行控制的方法

请求更新

在当前请求处于 进行中时, 若发起 相同请求, 则会触发请求更新,取消之前未完成的相同请求, 避免重复请求

e.g. 连续发起两个 相同 请求

TS
const get1 = http.get('/user?ID=12345')
setTimeout(()=>{
    const get2 = http.get('/user?ID=12345')
},200)

get1 在200ms内未请求完成,get2 发起请求时,get1 将被取消

具体业务场景 👇

  • 利用 sluggard-http 的请求更新机制

    • 无需从交互层面进行控制,sluggard-http 发起 相同 请求时,会自动 取消 之前未完成的相同请求,避免问题发生
    • 且对 相同 的定义可以自行设置级别。例如此处,无论用户携带的过滤查询条件是什么,只要是点击查询发起的,都应当视为相同请求。所以只需校验 请求方式&请求地址,相同便视为相同请求
    • 此时将级别配置为 path 即可👇(默认为 all,无需配置)
  • 使用方法

发起请求时在 RequestConfig (继承自 AxiosRequestConfig)中添加 updateLevel: "path"

ts
export async function getList(data: any) {
  const httpRes = await http.post(
    "/getList", 
    data, 
    { updateLevel: "path" } // RequestConfig
  );
  return httpRes;
}

updateLevelallpathfree 三个级别,详见 RequestConfig

全局请求清除

清除并 取消当前所有的请求, 往往在 路由变化时使用
  • sluggard-http 提供 clearPending() 方法,用于清除当前还未完成的所有请求
ts
// 以 vueRouter 为例,在路由守卫中进行配置
router.afterEach(() => {
  http.clearPending(); // 清除所有还未完成的请求
});
  • 如果某些请求需要设置不被清除,可在请求中单独配置

发起请求时在 RequestConfig (继承自 AxiosRequestConfig)中添加 canNotClear: true 即可

ts
export async function getList(data: any) {
  const httpRes = await http.post("/getList", data, {
    // 此请求不会被 clearPending() 清除
    canNotClear: true
  });
  return httpRes;
}

详见 RequestConfig

请求拦截

对还在 进行中指定请求进行拦截, 并 取消请求

请求拦截无视 RequestConfigcanNotClear 属性

  • sluggard-http 提供 abortPending() 方法,用于根据指定条件来拦截请求
    • abortPending() 方法接收一个 abortSign 参数,该参数可以是一个拦截标识符字符串,也可以是一个请求标识数组
ts
// 从请求 HttpPromise 对象中获取拦截标识符 abortSignUuidCode
const { abortSignUuidCode } = http
  .post("/getList", { size: 10, current: 1 })
  .then(function (response) {
    // ...
  })
  .catch(function (error) {
    // ...
  })
  .finally(function () {
    // ...
  });

// 通过 abortSignUuidCode 拦截请求
http.abortPending(abortSignUuidCode)
ts
http
  .post("/getList", { size: 10, current: 1 })
  .then(function (response) {
    // ...
  })
  .catch(function (error) {
    // ...
  })
  .finally(function () {
    // ...
  });

// 通过 [请求方式, 请求地址, 请求参数] 组成的请求标识数组来拦截请求
http.abortPending(["post", "/getList", { size: 10, current: 1 }]);

进度生命周期
new

sluggard-http 支持在单个请求开始/全部请求结束时抛出钩子函数

  • 常与 NProgress 等进度条插件配合使用

类型

ts
/**
 * 请求进度的生命周期
 * begin: 有请求开始时触发
 * end: 全部请求结束时触发
 */
interface LifeType {
  begin?: (config: HttpConfig) => void
  end?: () => void
}

示例 - 显示请求进度条

ts
import NProgress from "nprogress"; 
import { Http } from 'sluggard-http'

export const http = Http.create(
  {
    baseURL: '...',
    timeout: 1000,
    headers: {'Authorization': '...'}
  },
  { 
    methodAlias: { ... },  
    life: {  
      begin: () => {
        NProgress.start() 
      },
      end: () => {
        NProgress.done() 
      },
    },  
  } 
)