霸榜掘金!轻量级请求策略库 alova 出炉!

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

高级前端进阶

前言

今天在掘金上看到了一篇热文,题目是《是时候该换掉你的 axios 了》。当时眼前一亮,以为又有什么新请求方案出来了,以前也尝试讨论过 xhr、fetch、axios、甚至 Redaxios(体积只有 800 字节),看得出来大家对这一类文章都比较感兴趣,毕竟大多数情况下都需要面对它们。所以这次也一样,决定一探究竟,看看能给大家带来什么干货。

以下是已发布文章传送门:

话不多说,直接开始进入 alova 介绍的正题!

1.什么是 alova?

alova 是轻量级的请求策略库(注意策略两个字,与其他请求库有差异),它针对不同请求场景分别提供了具有针对性的请求策略,来提升应用可用性、流畅性,降低服务端压力,让应用如智者一般具备卓越的策略思维。

alova 核心模块提供了各类适配器接口(如:XMLHttpRequest、axios、Taro、Uniapp 等等),中间件机制来保证高扩展能力,从而适用更多的请求场景。

2.为什么需要 alova

数据请求一直是应用程序必不可少的重要部分,自从 XMLHttpRequest 诞生以来请求方案就层出不穷,客户端的数据交互探索一直聚焦于以下两个方向:

除了这两个方面外,其实开发者还应该更多的关注应用的流畅性,比如:减少频繁的、重复的请求,内存缓存优化都是可行的方向。 alova 从请求策略入手,一方面通过 Client-Server 数据交互的高效管理提高了应用的流畅性,另一方面还可以降低服务端压力,在此基础上逐渐演变成了 RSM 的请求场景模型(下文会重点论述)。

alova 的高可扩展能力可以实现不同场景下的请求策略,通过简单编码即可快速上手。

3.alova 优势

alova 可以在编写少量代码的情况下,开箱即用地提升应用在请求方面的流畅性,同时保证了开发体验。与常见的请求库相比,alova 在体积上也有明显的优势,是 axios 的(11.1/4.3)1/2.6 倍,是 react-query 的 1/3(4.3k/13k)。

因此,在包体积敏感的场景可以尝试使用 alova。当然,我曾经也介绍过一个更小的请求库,即 Redaxios,它体积只有 800 字节,远小于 alova。

Redaxios 使用浏览器原生 fetch() 以 800 字节的形式实现了该 API。所有现代主流浏览器都支持它,并且也扩展到了很多前端基建场景,如: Next.js、Create React App 和 Preact CLI 等等

同时,alova 也提供了丰富的特性,满足 99%的请求场景,alova 具有以下特性:

alova 的三种缓存模式分别对应于不同的场景,比如下面的内存模式:

lovaInstance.GET('/todo/list', {
  // ...
  localCache: {
    // 设置缓存模式为内存模式
    mode: 'memory',
    // 单位为毫秒
    // 当设置为`Infinity`,表示数据永不过期,设置为0或负数时表示不缓存
    expire: 60 * 10 * 1000,
  },
});

缓存占位模式下,data 将立即被赋值为上次缓存的旧数据,可以判断如果有旧数据则使用它替代 Loading 展示,同时它将发送请求获取最新数据并更新缓存,这样就达到了既快速展示实际数据,又获取了最新的数据。

const todoListGetter = alovaInstance.Get('/todo/list', {
  // ...
  localCache: {
    // 设置缓存模式为持久化占位模式
    mode: 'placeholder',
    // 缓存时间
    expire: 60 * 10 * 1000,
  },
});

恢复模式下,服务端缓存数据将持久化,如果过期时间未到即使刷新页面缓存也不会失效,它一般用于一些需要服务端管理,但基本不变的数据。

const todoListGetter = alovaInstance.Get('/todo/list', {
  // ...
  localCache: {
    // 设置缓存模式为持久化模式
    mode: 'restore',
    // 缓存时间
    expire: 60 * 10 * 1000,
  },
});

4.alova 和请求库的关系

4.1 什么是 RSM

alova 的创建初衷是对不同请求场景提出的一个解决方案,它可以更简洁优雅地实现体验更好,性能更好的请求功能,是一个 RSM(Request Scene Model) 实现库。

而例如:$.ajax、axios 和 fetch-api 等对请求发送和响应接收提供了很好的支持,它们是 RSM 流程中必不可少的一个环节(请求事件环节),alova 仍然需要依靠它们进行请求,因此我们可以将 alova 看作是请求库的一种武装,让请求库变得更加强大。

4.2 RSM 的 4 个阶段

请求时机

在 alova 中提供了 useRequest、useWatcher、useFetcher 三种 use hook 实现请求时机,由它们控制何时应该发出请求,同时将会创建和维护状态化的请求相关数据,如 loading、data、error 等,无需自主维护这些状态。

const App = () => {
  const {
    // loading是加载状态值,当加载时它的值为true,结束后自动更新为false
    // 它的值为普通的boolean值,请求状态变化时内部将自动调用set函数更新它的值
    loading,
    // 响应数据
    data,
    // 请求错误对象,请求错误时有值,否则为undefined
    error,
    // 直接将Method实例传入即可发送请求
  } = useRequest(todoListGetter, {
    // 请求响应前,data的初始值
    initialData: [],
  });
  // 你可以直接使用 todoList 来渲染 todo 列表
  if (loading) {
    return Loading...;
  } else if (error) {
    return {error.message};
  } else {
    return (
      <>
        
          {todo.title}
          {todo.time}
        
      
    );
  }
};

请求行为

描述以怎样的方式处理请求,在 alova 中以 method 对象实现。

const getTodoList = currentPage => {
    return alovaInstance.Get('/todo/list', {
        // 注意:这边设置了name属性,用于在无法直接指定Method实例时,过滤出需要的Method实例
        name: 'todoList',
        params: {
            currentPage,
            pageSize: 10
        }
    });
};
const App = () => {
    const {
        // fetching属性与loading相同,发送拉取请求时为true,请求结束后为false
        fetching,
        error,
        onSuccess,
        onError,
        onComplete,
        // 调用fetch后才会发送请求拉取数据,可以重复调用fetch多次拉取不同接口的数据
        fetch
    } = useFetcher();
    // 在事件中触发数据拉取
    const handleSubmit = () => {
        // 假设已完成todo项的修改...
        // 开始拉取更新后的数据
        // 情况1:当你明确知道拉取todoList第一页数据时,传入一个Method实例
        fetch(getTodoList(1));
        // 情况2:当你只知道拉取todoList最后一次请求的数据时,通过Method实例匹配器来筛选
        fetch({
            name: 'todoList',
            filter: (method, index, ary) => {
                // 返回true来指定需要拉取的Method实例
                return index === ary.length - 1;
            }
        });
    };
    return (
        {/* 渲染统一的拉取状态 */}
        { fetching ? {{ 正在后台拉取数据... }} : null }
        {/* ... */}
        
    );
};

请求事件

表示携带请求参数发送请求以获得响应,alova 可以与 axios、fetch、XMLHttpRequest 等任意请求库或原生方案共同协作。

下面使用 xhrRequestAdapter 作为 alova 的 xhr 请求适配器。

import { createAlova } from 'alova';
import { xhrRequestAdapter } from '@alova/adapter-xhr';
const alovaInst = createAlova(
  requestAdapter: xhrResponseAdapter(),
);

下面使用 axiosRequestAdapter 作为 alova 的请求适配器。

import { createAlova } from 'alova';
import { axiosRequestAdapter } from '@alova/adapter-axios';
const alovaInst = createAlova(
  requestAdapter: axiosResponseAdapter(),
);

下面调用 AdapterTaro 适配 taro 将返回请求适配器、存储适配器,以及 ReactHook,因此不需要设置这三个项,使用方法完全一致。

import { createAlova } from 'alova';
import AdapterTaro from '@alova/adapter-taro';
const alovaInst = createAlova(
  (baseURL: 'https://api.alovajs.org'),
  ...AdapterTaro()
);

响应数据管理

alova 将响应数据状态化,并统一管理,任何位置都可以对响应数据进行操作,并利用 MVVM 库的特性自动更新对应的视图。

当响应数据结构不能直接满足需求时,可以为 method 实例设置 transformData 钩子函数将响应数据转换成需要的结构,数据转换后将会作为 data 状态的值。

const todoListGetter = alovaInstance.Get('/todo/list', {
  params: {
    page: 1,
  },
  // 函数接受未加工的数据和响应头对象,并要求将转换后的数据返回,它将会被赋值给data状态。
  // 注意:rawData一般是响应拦截器过滤后的数据,响应拦截器的配置可以参考[设置全局响应拦截器]章节。
  transformData(rawData, headers) {
    return rawData.list.map((item) => {
      return {
        ...item,
        statusText: item.done ? '已完成' : '进行中',
      };
    });
  },
});

5.本文总结

文章到这里,大家应该都大概了解 alova 了,也明白为什么开头提示大家注意下请求策略库中的策略二字了。因为,alova 就不是一个请求库,这点和 xhr、fetch、axios、甚至 Redaxios 都有本质上的差异,前者是后者的进一步包装,相当于完整的、一体化的解决方案,至于底层请求库,则不作强依赖。

只是这种包装方案不是每个开发者都有述求,也不是所有项目都需要,所以从掘金的评论上看,大家并不怎么看好,认为是又一个轮子。目前 alova 在 github 上只有 100 个 star,为了鼓励下作者,毫不犹豫的支持了一下。值得一提的是,这个请求策略库的作者是国内的开发者,再次点赞一下吧!

不过,就我个人而言,我还是倾向于使用 Axios、如果包体积很敏感会尝试 Redaxios。不过,行文至此,就当一次对 alova 的宣传吧,毕竟开源不易!

参考资料

https://alova.js.org/zh-CN/overview/index

https://github.com/alovajs/alova

https://alova.js.org/zh-CN/extension/alova-adapter-taro

https://alova.js.org/

https://juejin.cn/post/7213923957824979000

https://www.npmjs.com/package/alova

https://alova.js.org/zh-CN/get-started/response-cache

展开阅读全文

页面更新:2024-02-09

标签:策略   适配器   缓存   服务端   体积   实例   场景   状态   模式   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top