<
>

一篇文章让你看懂封装Axios

2022-04-16 17:28:47 来源:易采站长站 作者:

目录
前言拦截器不要返回数据,依然返回 AxiosResponse 对象不推荐的做法推荐的做法为你的请求添加拓展支持请求重试支持 jsonp 请求支持 URI 版本控制保持请求唯一后语总结

前言

看很多网上的人的封装 Axios 教程,但或多或少都有不太合适的点,这里为大家推荐我的最佳实践。

拦截器不要返回数据,依然返回 AxiosResponse 对象

网上的文章都让你用 拦截器 直接返回数据,这种作法其实是非常不妥的,这样会让你后续的功能很难进行拓展。

不推荐的做法

import Axios from 'axios'const client = Axios.create({  // 你的配置})client.interceptors.response.use(response => {  // 网上的做法都是让你直接返回数据  // 这导致后续的一些功能难以支持  return response.data})export default client

推荐的做法

推荐使用函数代替拦截器

import Axios, { AxiosRequestConfig } from 'axios'const client = Axios.create({  // 你的配置})export async function request(url: string, config?: AxiosRequestConfig) {  const response = await client.request({ url, ...config })  const result = response.data  // 你的业务判断逻辑  return result}export default client

到这里可能有人会说太麻烦,请稍等,继续往下看。

为你的请求添加拓展

很多时候,我们的开发流程是这样的:

发送请求 => 拿到数据 => 渲染内容

但可惜的是,这只是理想情况,在某些特殊情况下,你还是需要处理异常或额外的支持,如:

当请求失败,希望能够自动重试3次以上再失败分页数据中,当新的请求发出,自动中断上一次的请求第三方提供 jsonp 接口,而你又只能使用静态页时 (ps: Axios 不支持 jsonp)更多

当发送以上场景时,你只能默默的写代码支持,但如果你不拦截 Axios 的响应,那就可以使用开源社区提供的方案。

支持请求重试

安装 axios-retry,可以让你的 Axios 支持自动重试的功能

import Axios, { AxiosRequestConfig } from 'axios'import axiosRetry from 'axios-retry'const client = Axios.create({  // 你的配置})// 安装 retry 插件// 当请求失败后,自动重新请求,只有3次失败后才真正失败axiosRetry(client, { retries: 3 })export async function request(url: string, config?: AxiosRequestConfig) {  const response = await client.request({ url, ...config })  const result = response.data  // 你的业务判断逻辑  return result}// 只有3次失败后才真正失败const data = request('http://example.com/test')

PS: axios-retry 插件支持配置单个请求

支持 jsonp 请求

安装 axios-jsonp,可以让你的 Axios 支持 jsonp 的功能。

import Axios, { AxiosRequestConfig } from 'axios'import jsonpAdapter from 'axios-jsonp'const client = Axios.create({  // 你的配置})export async function request(url: string, config?: AxiosRequestConfig) {  const response = await client.request({ url, ...config })  const result = response.data  // 你的业务判断逻辑  return result}export function jsonp(url: string, config?: AxiosRequestConfig) {  return request(url, { ...config, adapter: jsonpAdapter })}// 你现在可以发送 jsonp 的请求了const data = jsonp('http://example.com/test-jsonp')

支持 URI 版本控制

有开发 Web API 经验的人都会遇到一个问题,如果 API 出现重大变更的时候,如何保证旧版可用的情况下,发布新的 API?

这种情况在服务端开发场景中,其实并不罕见,尤其是os from 'axios'const CancelToken = Axios.CancelTokenexport function withCancelToken(fetcher) { let abort function send(data, config) { cancel() // 主动取消 const cancelToken = new CancelToken(cancel => (abort = cancel)) return fetcher(data, { ...config, cancelToken }) } function cancel(message = 'abort') { if (abort) { abort(message) abort = null } } return [send, cancel]}

使用

function getUser(id: string, config?: AxiosRequestConfig) {  return request(`api/user/${id}`, config)}// 包装请求函数const [fetchUser, abortRequest] = withCancelToken(getUser)// 发送请求// 如果上一次请求还没回来,会被自动取消fetchUser('1000')// 通常不需要主动调用// 但可以在组件销毁的生命周期中调用abortRequest()

这样不需要自动取消的时候,直接使用原函数即可,也不会影响原函数的使用

后语

Axios 封装其实还有很多事情可以做,比如 全局错误处理 (一样不能影响正常请求) 等,封装也不应该只是利用拦截器直接返回数据。

另外请求模块应该保持独立,推荐拓展 AxiosRequestConfig 或做成一个个独立的函数,提供给外部调用,方便做成一个独立的 HTTP 模块。

总结

暂时禁止评论

微信扫一扫

易采站长站微信账号