dw网站设计与制作,登录wordpress建立数据库,oray免费域名注册,管理咨询和战略咨询大家好#xff0c;我是若川。欢迎加我微信 ruochuan12#xff0c;长期交流学习。今天推荐这篇Axios缓存请求数据的文章#xff0c;相信是常见的业务场景#xff0c;感兴趣的读者可以看看 umi-request#xff0c;支持缓存功能。另外我之前也写过 axios源码文章#xff0c;… 大家好我是若川。欢迎加我微信 ruochuan12长期交流学习。今天推荐这篇Axios缓存请求数据的文章相信是常见的业务场景感兴趣的读者可以看看 umi-request支持缓存功能。另外我之前也写过 axios源码文章是转载次数16次最多的一篇文章好久没写好文章了惭愧惭愧。点击下方卡片关注我或者查看源码等系列文章。学习源码整体架构系列、年度总结、JS基础系列在 Axios 如何取消重复请求 这篇文章中阿宝哥介绍了在 Axios 中如何取消重复请求及 CancelToken 的工作原理。本文将介绍在 Axios 中如何通过增强默认适配器来缓存请求数据。那么为什么要缓存请求数据呢这是因为在缓存未失效时我们可以直接使用已缓存的数据而不需发起请求从服务端获取数据这样不仅可以减少 HTTP 请求而且还能减少等待时间从而提高用户体验。因为本文将使用 Axios 提供的默认适配器来实现缓存请求数据的功能所以如果你对 Axios 适配器还不熟悉的话建议先阅读 77.9K 的 Axios 项目有哪些值得借鉴的地方 这篇文章。为了让大家能够更好地理解后续的内容我们先来看一下整体的流程图上图中蓝色部分的工作流程就是本文的重点。接下来阿宝哥将从如何设计缓存开始带大家一起来开发缓存请求数据的功能。一、如何设计缓存在计算中缓存是一个高速数据存储层其中存储了数据子集且通常是 短暂性 存储这样日后再次请求该数据时速度要比访问数据的主存储位置快。通过缓存你可以高效地重用之前检索或计算的数据。了解完缓存的作用之后我们来设计缓存的 APIget(key)从缓存中获取指定 key 对应的值delete(key)从缓存中删除指定 key 对应的值clear()清空已缓存的数据set(key, value, maxAge)保存键值对同时支持设置缓存的最大时间即 maxAge 单位为毫秒。基于上述的缓存 API我们可以实现一个简单的缓存功能具体代码如下所示const MemoryCache {data: {},set(key, value, maxAge) { // 保存数据this.data[key] {maxAge: maxAge || 0,value,now: Date.now(),};},get(key) { // 从缓存中获取指定 key 对应的值。const cachedItem this.data[key];if (!cachedItem) return null;const isExpired Date.now() - cachedItem.now cachedItem.maxAge;isExpired this.delete(key);return isExpired ? null : cachedItem.value;},delete(key) { // 从缓存中删除指定 key 对应的值。return delete this.data[key];},clear() { // 清空已缓存的数据。this.data {};},
};
其实除了自定义缓存对象之外你也可以使用成熟的第三方库比如 lru-cache。LRU 缓存淘汰算法就是一种常用策略。LRU 的全称是 Least Recently Used也就是说我们认为最近使用过的数据应该是是「有用的」很久都没用过的数据应该是无用的内存满了就优先删那些很久没用过的数据。二、如何增强默认适配器Axios 引入了适配器使得它可以同时支持浏览器和 Node.js 环境。对于浏览器环境来说它通过封装 XMLHttpRequest API 来发送 HTTP 请求而对于 Node.js 环境来说它通过封装 Node.js 内置的 http 和 https 模块来发送 HTTP 请求。在介绍如何增强默认适配器之前我们先来回顾一下 Axios 完整请求的流程了解完 Axios 完整请求的流程之后我们再来看一下 Axios 内置的 xhrAdapter 适配器它被定义在 lib/adapters/xhr.js 文件中// lib/adapters/xhr.js
module.exports function xhrAdapter(config) {return new Promise(function dispatchXhrRequest(resolve, reject) {var requestData config.data;var requestHeaders config.headers;var request new XMLHttpRequest();// 省略大部分代码var fullPath buildFullPath(config.baseURL, config.url);request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);// Set the request timeout in MSrequest.timeout config.timeout;// Listen for ready staterequest.onreadystatechange function handleLoad() { ... }// Send the requestrequest.send(requestData);});
};
很明显 xhrAdapter 适配器是一个函数对象它接收一个 config 参数并返回一个 Promise 对象。而在 xhrAdapter 适配器内部最终会使用 XMLHttpRequest API 来发送 HTTP 请求。为了实现缓存请求数据的功能我们就可以考虑通过高阶函数来增强 xhrAdapter 适配器的功能。2.1 定义辅助函数2.1.1 定义 generateReqKey 函数在增强 xhrAdapter 适配器之前我们先来定义一个 generateReqKey 函数该函数用于根据当前请求的信息生成请求 Keyfunction generateReqKey(config) {const { method, url, params, data } config;return [method, url, Qs.stringify(params), Qs.stringify(data)].join();
}
通过 generateReqKey 函数生成的请求 key将作为缓存项的 key而对应的 value 就是默认 xhrAdapter 适配器返回的 Promise 对象。2.1.2 定义 isCacheLike 函数isCacheLike 函数用于判断传入的 cache 参数是否实现了前面定义的 Cache API利用该函数我们允许用户为每个请求自定义 Cache 对象。function isCacheLike(cache) {return !!(cache.set cache.get cache.delete cache.clear typeof cache.get function typeof cache.set function typeof cache.delete function typeof cache.clear function);
}
2.2 定义 cacheAdapterEnhancer 函数为了让用户能够更灵活地控制数据缓存的功能我们定义了一个 cacheAdapterEnhancer 函数该函数支持两个参数adapter预增强的 Axios 适配器对象options缓存配置对象该对象支持 4 个属性分别用于配置不同的功能maxAge全局设置缓存的最大时间enabledByDefault是否启用缓存默认为 truecacheFlag缓存标志用于配置请求 config 对象上的缓存属性defaultCache用于设置使用的缓存对象。了解完 cacheAdapterEnhancer 函数的参数之后我们来看一下该函数的具体实现function cacheAdapterEnhancer(adapter, options) {const { maxAge, enabledByDefault true,cacheFlag cache, defaultCache MemoryCache,} options;return (config) {const { url, method, params, forceUpdate } config;let useCache config[cacheFlag] ! undefined config[cacheFlag] ! null? config[cacheFlag]: enabledByDefault;if (method get useCache) {const cache isCacheLike(useCache) ? useCache : defaultCache;let requestKey generateReqKey(config); // 生成请求Keylet responsePromise cache.get(requestKey); // 从缓存中获取请求key对应的响应对象if (!responsePromise || forceUpdate) { // 缓存未命中/失效或强制更新时则重新请求数据responsePromise (async () {try {return await adapter(config); // 使用默认的xhrAdapter发送请求} catch (reason) {cache.delete(requestKey);throw reason;}})();cache.set(requestKey, responsePromise, maxAge); // 保存请求返回的响应对象return responsePromise; // 返回已保存的响应对象}return responsePromise;}return adapter(config); // 使用默认的xhrAdapter发送请求};
}
以上的代码并不会复杂核心的处理逻辑如下图所示2.3 使用 cacheAdapterEnhancer 函数2.3.1 创建 Axios 对象并配置 adapter 选项const http axios.create({baseURL: https://jsonplaceholder.typicode.com,adapter: cacheAdapterEnhancer(axios.defaults.adapter, {enabledByDefault: false, // 默认禁用缓存maxAge: 5000, // 缓存时间为5s}),
});
2.3.2 使用 http 对象发送请求// 使用缓存
async function requestWithCache() {const response await http.get(/todos/1, { cache: true });console.dir(response);
}// 不使用缓存
async function requestWithoutCache() {const response await http.get(/todos/1, { cache: false });console.dir(response);
}
其实 cache 属性除了支持布尔值之外我们可以配置实现 Cache API 的缓存对象具体的使用示例如下所示const customCache { get() {/*...*/}, set() {/*...*/}, delete() {/*...*/}, clear() {/*...*/}};async function requestForceUpdate() {const response await http.get(/todos/1, {cache: customCache,forceUpdate: true,});console.dir(response);
}
好了如何通过增强 xhrAdapter 适配器来实现 Axios 缓存请求数据的功能已经介绍完了。由于完整的示例代码内容比较多阿宝哥就不放具体的代码了。感兴趣的小伙伴可以访问以下地址浏览示例代码。完整的示例代码https://gist.github.com/semlinker/b8a7bd5a0a16c2d04011c2c4a8167fbd三、总结本文介绍了在 Axios 中如何缓存请求数据及如何设计缓存对象基于文中定义的 cacheAdapterEnhancer 函数你可以轻松地扩展缓存的功能。在后续的文章中阿宝哥将会介绍在 Axios 中如何实现请求重试功能感兴趣的小伙伴不要错过哟。另外如果你对 Axios 如何取消重复请求感兴趣可以阅读 Axios 如何取消重复请求 这篇文章。四、参考资源77.9K 的 Axios 项目有哪些值得借鉴的地方Axios 如何取消重复请求Github - axios-extensions最近组建了一个江西人的前端交流群如果你也是江西人可以加我微信 ruochuan12 拉你进群。················· 若川出品 ·················今日话题建的江西前端交流群感觉氛围不错想着要不要建其他省份的交流群不过我是江西人建其他省份的会不会有人进群是个问题~。欢迎分享、收藏、点赞、在看我的公众号文章~一个愿景是帮助5年内前端人走向前列的公众号可加我个人微信 ruochuan12长期交流学习推荐阅读我在阿里招前端我该怎么帮你现在还能加我进模拟面试群如何拿下阿里巴巴 P6 的前端 Offer点击上方卡片关注我或者查看源码等系列文章。学习源码整体架构系列、年度总结、JS基础系列