Axios 是一个基于 Promise 的 HTTP 客户端,每周 npm 下载量超过 4000 万。 如果回到10年前,promise式的请求工具是一个伟大的创新。 它解决了繁琐的请求问题。 没有那么高的年龄可以说是最好的了。 但是随着时间的推移,Axios在开发效率和性能上开始落后。 现在是2023年,面对越来越复杂的需求,我们需要的是更创新、更领先的请求工具,而promise式的请求工具,要想走在前列,只能称之为传统。 的快速发展,那么请继续阅读。
首先声明一下,我真的不是头条党。 接下来,我会随着时间的推移,揭露axios在某些方面的不足,并推荐一个比axios更现代、更创新的新request。 工具给你,它是【轻量级请求策略库alova】(https://alova.js.org/)
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/'
})
// 在响应拦截中返回响应数据
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 => {
// 结果的类型总是 axios.AxiosResponse<Resp>
console.log(result.data);
})
不知道axios是故意的还是忽略了。 在上面发起的GET请求中,响应数据的result
类型始终是axios.AxiosResponse<Resp>
相同,但实际上我们已经在响应拦截器response.data
中返回了,这就导致了混淆 响应数据类型。
在alova中是怎么解决的?
作为更现代、更适应复杂应用的请求解决方案,alova 也提供了更优雅的解决方案。 同时为了降低学习成本,还保留了类似axios的api设计,看起来很眼熟。
Alova 发音为“Alova”。 虽然是以一个like axios开头的,但是下面两个名字需要区分一下!
与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 } from 'alova';
const pageData = createAlova({ baseURL: 'http://xxx' }).Get('/index');
const { loading, data, error } = useRequest(pageData);
</script>
在axios中,你需要创建相应的请求状态并自己维护,但是alova为你接管了这个工作
开箱即用的高性能特性
传统的 Promise 风格的请求工具主要定位是通过 Promise 简化请求,提升性能可能是他们考虑最少的。 但是,请求策略库Alova强调了这一点。 在 Alova 中,默认情况下启用内存。 缓存和请求共享,这两个可以极大的提升请求性能,提升用户体验,减轻服务器压力,我们一一来看。
内存缓存
内存模式是在响应请求后,将响应数据保存在本地内存中。 下次再发起同样的请求时,将使用缓存的数据,而不是再次发送请求。 想象一下,当你在实现一个列表页时,点击列表项就可以进入详情页查看数据。 你会认为用户可能会经常点击查看列表中的详细信息。 在详情数据没有变化的情况下,每次进入详情页请求一次,每次都需要用户等待加载,太浪费了。 在alova中默认可以享受这样的待遇,效果如下图
request to share
您可能遇到过这种情况。 当一个请求发送但未被响应时,再次发起同一个请求,造成请求浪费,或者重复提交的问题,比如以下三种场景:
- 组件创建时,会获取初始化数据。 当一个页面同时渲染多个组件时,会同时发送多个相同的请求;
- 提交按钮未被禁用,用户多次点击提交按钮;
- 预加载完成前进入预加载页面时,会多次发起同一个请求;
分享请求就是用来解决这些问题的。 它是通过多路复用请求来实现的。 由于这种情况不能直观展示,就不展示了。 有兴趣的小伙伴可以自行体验。
另外,自称是请求策略库的alova也提供了特定场景下的请求策略,下面我们会介绍。 感兴趣的小伙伴,请继续往下看。
轻量化
压缩状态下的Alova只有4kb+,只有axios的30%+,不信的话可以点这里查看
更直观的响应数据TS类型
在axios中,要定义响应数据的类型,真是让人费解。 如果你是 Typescript 的重度用户,alova 可以为你提供完整的字体体验。 当你在请求处定义响应数据的类型时,你可以在多个地方享受它,它会让你感觉很清晰,我们来看看。
interface Resp {
id: number
}
const pageData = createAlova({ baseURL: 'http://xxx' }).Get<Resp>('/index');
const {
data, // 数据类型为 Resp
loading, error, onSuccess, send
} = useRequest(pageData);
onSuccess(event => {
// event.data 的类型也是 Resp
console.log(event.data);
});
const handleClick = async () => {
// 您可以调用发送再次发送请求。 它可以接收类型也是 Resp 的响应
const data = await send();
}
至此,相对于传统的Promise风格的请求库,你可能对alova的强大有了初步的了解。
但是……它的意义远不止于此!
alova 的其他功能
同时支持多个UI框架
Alova同时支持react、vue、svelte,无论你使用哪种UI框架,它都能满足你。
类似axios的API设计,更易用,熟悉
Alova的请求信息结构和axios几乎一样。 让我们比较一下他们的 GET 和 POST 请求。
GET request
// axios
axios.get('/index', {
// set request headers
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
// set params
params: {
userId: 1
}
});
// alova
const todoListGetter = alovaInstance.Get('/index', {
// set request headers
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
// set params
params: {
userId: 1
}
});
POST request
// axios
axios.post('/login', {
username: 'xxx',
password: 'ppp'
}, {
// set request headers
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
// set params
params: {
userId: 1
}
});
// alova
const loginPoster = alovaInstance.Post('/login', {
username: 'xxx',
password: 'ppp'
}, {
// set request headers
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
// set params
params: {
userId: 1
}
});
(Request strategy) 高性能分页请求策略
自动维护分页相关数据和状态,提供通用的分页数据操作能力。 据官方介绍,可提升列表页流畅度300%,编码难度降低50%。 下面是官方提供的例子。 有兴趣的同学可以去看看。
(请求策略)非感应式数据交互
在我看来,这种无感数据交互请求策略可谓是一个伟大的创举。 我将其理解为更可靠的乐观更新。 官网是这样解释的:
无感数据交互是指用户与应用进行交互时,可以立即显示相关内容,无需等待,或者在提交信息时,无需等待,直接显示操作结果,就像与本地数据进行交互一样,从而大大提高了流畅度 该应用让用户感受不到数据传输带来的滞后。 它可以最大程度地减少网络波动带来的问题,您的应用程序在高延迟网络甚至断开的网络上仍然可用。
在我的体验过程中,即使在弱网状态下,也能感受到毫不拖延的流畅感,欢迎大家前来体验。
据我了解,它使用以下技术:
1、持久化的请求队列,保证请求的安全性和序列化; 2.请求重试策略机制,保证请求的顺利完成; 3. 虚拟响应数据(一个创新概念)用作无响应数据的占位符,以便在响应后可以定位并用实际数据替换。
关于无感数据交互的更多细节,可以在官网了解更多
数据预取
数据通过拉取数据进行预加载,缓存在本地。 这部分数据在实际使用时,可以打缓存直接显示数据。 这种方式也大大提高了用户体验。
##写在最后
总之,alova作为新一代的请求工具,潜力巨大。 如果您想尝试一下,可以单击下面的链接了解更多信息。