[热文]是时候该换掉你的axios了

image.png

转载自https://juejin.cn/post/7213923957824979000

话题火热讨论中...

image.png

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,看下图

image.png

链接在此

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中你可以默认享受到这样的待遇,以下展示下效果

image.png

请求共享

你可能遇到过这种情况,当一个请求发出但还未响应时,又发起了相同请求,就造成了请求浪费,或者重复提交问题,例如以下三种场景:

  1. 一个组件在创建时会获取初始化数据,当一个页面同时渲染多个此组件时,将会同时发出多次相同请求;
  2. 提交按钮未被禁用,用户点击了多次提交按钮;
  3. 当预加载还未完成时进入了预加载页面,将会发起多次相同请求;

共享请求就是用来解决这些问题的,它是通过复用请求的方式来实现的,由于这种案例无法直观展示,就不展示了,有兴趣的小伙伴可以自行体验体验。

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

轻量级的体积

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

image.png

链接在此

更加直观的响应数据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%,以下是官方提供的示例,有兴趣的同学可以去看看。

分页列表示例

下拉加载示例

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

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

无感数据交互是指用户在与应用进行交互时,无需等待即可立即展示相关内容,或者提交信息时也无需等待即可展示操作结果,就像和本地数据交互一样,从而大幅提升应用的流畅性,它让用户感知不到数据传输带来的卡顿。可以更高限度地降低网络波动带来的问题,你的应用在高延迟网络甚至是断网状态下依然可用。

在我的体验过程中,即使在弱网状态下,也可以让我感受到一种毫无延迟带来的顺畅感,你也来感受下吧。

image.png

据我了解,它使用以下技术:

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

关于无感数据交互更具体的可以在官网了解哦

数据预拉取

通过拉取数据的方式预先加载好数据并缓存在本地,当真正用到这部分数据时就可以命中缓存并直接显示数据,这种方式也极大地提升了用户体验。

写在最后

总之,alova作为一个新生代的请求工具,具有很大的潜力,你也想试用的话,可以点击以下链接去了解。
alova官网
alova的Github地址
写作不易,看都看到这了,不如帮我点个免费的爱心吧!!!感谢你的喜欢

----- 2023年3月26日更新 -----

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

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

与大家承诺的3月29日(周三)再和大家聊聊对编程思想的深度理解文章,已发布。

链接在这:(深度)开源框架/库的伟大与罪恶

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容