乐趣区

关于前端:是时候该换掉你的axios了

本文转发自 https://juejin.cn/post/7213923957824979000
目前热榜第一正在探讨的问题

axios 是一个基于 Promise 的 HTTP 客户端,每周的 npm 下载量 4000W+,如果回到在 10 年前,promise 式的申请工具是一个很大的翻新,它解决了申请繁琐的问题,在那个性能要求不那么高的年代堪称是一骑绝尘。但随着工夫的推移,Axios 在开发效率和性能方面开始有所落后,当初都曾经是 2023 年了,面对日益简单的需要,咱们须要的是一款更具创新性和当先性的申请工具,而 promise 式的申请工具只能被称为 传统 了,如果你想放弃在疾速倒退的前沿,那么请持续浏览。

首先我想申明的是,我的确不是题目党,接下来我将通过裸露随着工夫的推移,axios 在一些方面体现的力不从心,并举荐一个新的,相比 axios 更具现代化和创新性的申请工具给你,它就是 轻量级的申请策略库 alova

接下来咱们看看 Promise 式申请工具的弱点(axios)

1. 与 React、Vue 等框架割裂

当初,React、Vue 等前端 UI 框架对于前端来说简直是不可短少的,axios 无奈和这些框架的状态深度绑定,须要开发者自行保护它们,导致开发效率较低。

2. 在性能方面毫无作为

2023 年了,相比 10 年前的利用曾经简单了不知几个数量级,在申请方面要求也越来越高,来保障页面性能的要求,axios 在这方面毫无作为,例如在频繁地反复申请、同时发动多个雷同申请等场景。

3. 臃肿的体积

依据 bundlephobia 显示,axios 的体积在压缩状态下有 11+kb,看下图

链接在此

4. 响应数据的 Ts 类型定义凌乱

在应用 axios 时,你可能常常会这样写:

// 创立一个 axios 实例
const inst = axios.create({baseURL: 'https://example.com/'})

// 在响应拦截器中返回 data
inst.interceptors.response.use(response => {if (response.status === 200) {return response.data}
  throw new Error(response.status)
})

interface Resp {id: number}
inst.get<Resp>('/xxx').then(result => {
  // result 的类型总是为 axios.AxiosResponse<Resp>
  data.data
})

不晓得是 axios 成心为之还是疏忽了,以上的发动的 GET 申请中,响应数据 result 的类型总是 axios.AxiosResponse<Resp> 的,但其实咱们在响应拦截器中曾经将 response.data 返回了,这导致响应数据类型凌乱而被困扰。

在 alova 中是如何解决的呢?

alova 作为一个更加现代化,更加适应简单利用的申请计划,也给出了它更加优雅的解决方案。同时为了升高给的学习老本,也放弃了和 axios 类似的 api 设计,看起来就很相熟有木有。

alova 读作“阿洛娃”,尽管和 axios 一样都是以 a 结尾,以下两个名称须要留神辨别哦!

与 UI 框架深度交融,主动治理申请相干数据

假如咱们须要发动一个根本的数据获取申请,以 vue 为例,间接上比照代码。

axios

<template>
  <div v-if="loading">Loading...</div>
  <div v-else-if="error" class="error">
    {{error.message}}
  </div>
  <div v-else>{{data}}</div>
</template>

<script setup>
import axios from 'axios';
import {ref, onMounted} from 'vue';

const loading = ref(false);
const error = ref(null);
const data = ref(null);

const requestData = () => {
  loading.value = true;
  axios.get('http://xxx/index').then(result => {data.value = result;}).catch(e => {error.value = e;}).finally(() => {loading.value = false;});
}
onMounted(requestData);
</script>

alova

<template>
  <div v-if="loading">Loading...</div>
  <div v-else-if="error" class="error">
    {{error.message}}
  </div>
  <div v-else>{{data}}</div>
</template>

<script setup>
import {createAlova, useRequest} from 'alova';

const pageData = createAlova({baseURL: 'http://xxx'}).Get('/index');
const {loading, data, error} = useRequest(pageData);
</script>

在 axios 中须要本人创立对应的申请状态并自行保护,而 alova 却帮你接管了这项工作

开箱即用的高性能性能

传统 Promise 式的申请工具次要定位于通过 Promise 的形式简化申请,而进步性能可能是它们最不会思考的一点,但作为申请策略库的 alova 中却着重突出这一点,在 alova 中默认开启了内存缓存和申请共享,这两项能够极大地提高申请性能,晋升用户体验的同时还能升高服务端压力,让咱们来一一理解下它们吧。

内存缓存

内存模式就是在申请响应后将响应数据保留在本地内存中,当下次再发动雷同申请时就会应用缓存数据,而不会再次发送申请,试想一下,当你在实现一个列表页,点击列表项能够进入详情页查看数据,你会想到用户可能会频繁在列表中点击查看详情,当详情数据没有变动时,如果每一次进入详情页都要申请一次未免也太节约了,而且每次还须要用户期待加载。在 alova 中你能够默认享受到这样的待遇,以下展现下成果

申请共享

你可能遇到过这种状况,当一个申请收回但还未响应时,又发动了雷同申请,就造成了申请节约,或者反复提交问题,例如以下三种场景:

  1. 一个组件在创立时会获取初始化数据,当一个页面同时渲染多个此组件时,将会同时收回屡次雷同申请;
  2. 提交按钮未被禁用,用户点击了屡次提交按钮;
  3. 当预加载还未实现时进入了预加载页面,将会发动屡次雷同申请;

共享申请就是用来解决这些问题的,它是通过复用申请的形式来实现的,因为这种案例无奈直观展现,就不展现了,有趣味的小伙伴能够自行体验体验。

除此以外,自称是申请策略库的 alova 还提供了特定场景下的申请策略,咱们将在下文中介绍,有趣味的小伙伴请持续往下看。

轻量级的体积

压缩状态下的 alova 只有 4kb+,只有 axios 的 30%+,看上面截图

链接在此

更加直观的响应数据 TS 类型

在 axios 中,你想要定义响应数据的类型真是会让人感到困惑,如果你是个 Typescript 的重度用户,alova 能够给你提供残缺的类型体验,当你在申请处定义响应数据时的类型后,你能够在多处享受到它,会让你感觉很清晰,咱们来看看。

interface Resp {id: number}
const pageData = createAlova({baseURL: 'http://xxx'}).Get<Resp>('/index');
const {
  data,  // data 的类型为 Resp
  loading, error, onSuccess, send
} = useRequest(pageData);
onSuccess(event => {
  // 在胜利回调中获取响应数据时,event.data 的值类型也是 Resp
  console.log(event.data);
});

const handleClick = async () => {
  // send 函数能够手动再次发送申请,它将能够接管到响应数据,它的值类型还是 Resp
  const data = await send();}

至此,相比传统的 Promise 式申请库,你可能曾经初步理解了 alova 的厉害。

但 … 它的个性还远不止于此!

alova 的其余个性

多 UI 框架同时反对

alova 同时反对 react、vue、svelte,无论你应用哪种 UI 框架,它都能满足你。

与 axios 类似的 api 设计,用起来更简略相熟

alova 的申请信息结构简直和 axios 雷同,咱们来比照一下它们的 GET 和 POST 申请。

GET 申请

// axios
axios.get('/index', {
  // 设置申请头
  headers: {'Content-Type': 'application/json;charset=UTF-8'},
  // params 参数
  params: {userId: 1}
});

// alova
const todoListGetter = alovaInstance.Get('/index', {
  // 设置申请头
  headers: {'Content-Type': 'application/json;charset=UTF-8'},
  // params 参数
  params: {userId: 1}
});

POST 申请

// axios
axios.post('/login', {
  username: 'xxx',
  password: 'ppp'
}, {
  // 设置申请头
  headers: {'Content-Type': 'application/json;charset=UTF-8'},
  // params 参数
  params: {userId: 1}
});

// alova
const loginPoster = alovaInstance.Post('/login', {
  username: 'xxx',
  password: 'ppp'
}, {
  // 设置申请头
  headers: {'Content-Type': 'application/json;charset=UTF-8'},
  // params 参数
  params: {userId: 1}
});

(申请策略)高性能分页申请策略

主动保护分页相干数据和状态,并提供了罕用的分页数据操作能力,据官网介绍,能够让列表页流畅性进步 300%,编码难度升高 50%,以下是官网提供的示例,有趣味的同学能够去看看。

分页列表示例

下拉加载示例

(申请策略)无感数据交互

这个在我看来,这个无感数据交互申请策略堪称是一大创举,我把它了解为更加牢靠的乐观更新,官网是这样解释的:

无感数据交互是指用户在与利用进行交互时,无需期待即可立刻展现相干内容,或者提交信息时也无需期待即可展现操作后果,就像和本地数据交互一样,从而大幅晋升利用的流畅性,它让用户感知不到数据传输带来的卡顿。能够更高限度地升高网络稳定带来的问题,你的利用在高提早网络甚至是断网状态下仍然可用。

在我的体验过程中,即便在弱网状态下,也能够让我感触到一种毫无提早带来的顺畅感,你也来感触下吧。

据我理解,它应用以下技术:

  1. 长久化的申请队列来保障申请的安全性和串联性;
  2. 申请重试策略机制,来保障申请的顺利完成;
  3. 虚构响应数据(一个翻新的概念),来作为未响应时的数据占位,以便在响应后定位它并替换为理论数据。

对于无感数据交互更具体的能够在官网理解哦

数据预拉取

通过拉取数据的形式事后加载好数据并缓存在本地,当真正用到这部分数据时就能够命中缓存并间接显示数据,这种形式也极大地晋升了用户体验。

写在最初

总之,alova 作为一个新生代的申请工具,具备很大的后劲,你也想试用的话,能够点击以下链接去理解。

alova 官网

alova 的 Github 地址

写作不易,看都看到这了,不如帮我点个收费的爱心吧!!!感激你的喜爱

—– 2023 年 3 月 26 日更新 —–

😁感激大家对这篇文章的反馈,我也认真看了每条评论,不过对于有些评论的确不太认同。

在大家的反馈中我发现,很多人的开发思维都还停留在应用层面,而短少深度的了解和思考

我会在 3 月 29 日周三再发一篇我对编程思维的了解,和大家更深刻地聊聊这方面的货色,到时候我会把链接发在评论中。

刚发了一个评论说这个的,后果沉没了😂

退出移动版