不用防抖和节流,用更底层的方式解决JS的重复请求

简介: 成员A成员B都用得上一个后端接口api,但它们互相不知道对方什么时候请求这个接口,因此导致一打开页面,同一个接口竟然重复请求了多次。

你或许在项目中遇到过这样的情况。

  1. 成员A成员B都用得上一个后端接口api,但它们互相不知道对方什么时候请求这个接口,因此导致一打开页面,同一个接口竟然重复请求了多次。
  2. 由于用户手抖,又因为成员忘记做请求的loading防误触处理,导致一个接口被用于疯狂请求,最终数据乱套,页面不可用。
  3. SPA单页面应用,多个页面甚至是多个组件可能有同样的数据请求,完全可以共享的数据却不得不重复请求,影响页面加载效率。
  4. 想要用节流或者防抖解决上面的问题,但是后端返回数据的时间浮动太大,导致不知道应该设置多长的时间。

这些请求浪费,实际上都有调用异步函数(async function)的参与的;因此,它们虽不是async function的问题,但却可以利用async function的特点来解决。

async function本质上是一个Promise。因此只要利用好Promise的特性,就能解决这些问题。

once-init 正是为解决这些问题而生。它从 Promise 的定义出发,用 Promise 的基础功能彻底地阻止了异步请求浪费的发生。

我用它做了两件事:

  1. 缓存请求的返回值;
  2. 缓存Promise请求本身

原理

once-init 的核心思想是缓存和执行队列;

缓存返回值

实现缓存返回值并不困难,只要写一个单例模式就好了。下面是一个缓存的单例模式的简单示例;



  1. 如果缓存已经有值,返回缓存的值;
  2. 如果缓存没有值,执行异步函数;执行完毕后,更新缓存;

这是一个简易的解决方案,它大概能解决10%的异步函数相关的问题,因为在第一次执行Promise完成之后,就不会再进行请求,也就不会产生浪费了;

但是,它没有解决多个Promise同时发生的情况。

假设开发人员同一时间多次调用init,如果第一次调用的Promise还没有完成,cache也还没有初始化,就会导致同一时间的所有调用依旧创建新的Promise

甚至有可能因为多次请求,不断的变化cache,你甚至没有办法确定最后cache的值是不是你最后一次请求的返回值。

如果要解决这个问题,就需要利用Promise的特性,同一时间,同一个async function,只允许同一个Promise处在pending状态

缓存 Promise

  1. 如果Promise正在执行,就不创建新的Promise;直接返回正在执行的Promise的返回值;
  2. 如果没有Promise正在执行,就创建并缓存新的Promise
  1. Promise执行结束之后,删除缓存的Promise

通过这种方式,就能避免promise同一时间重复执行。这也是once-init这个库的核心思想。

当然这个简单实现还有很多问题需要解决。

通过这种方式,就能避免promise同一时间重复执行。这也是once-init这个库的核心思想。

相关文章
|
9月前
|
JavaScript 前端开发 开发者
Nest.js控制器深度解析:路由与请求处理的高级特性
以上就是对 NestJS 控制层高级特性深度解析:从基本概念到异步支持再到更复杂场景下拦截其与管道等功能性组件运用都有所涉及,希望能够帮助开发者更好地理解和运用 NestJS 进行高效开发工作。
496 15
|
12月前
|
JavaScript 前端开发 API
Node.js中发起HTTP请求的五种方式
以上五种方式,尽管只是冰山一角,但已经足以让编写Node.js HTTP请求的你,在连接世界的舞台上演奏出华丽的乐章。从原生的 `http`到现代的 `fetch`,每种方式都有独特的风格和表现力,让你的代码随着项目的节奏自由地舞动。
986 65
|
前端开发 JavaScript UED
JavaScript防抖和节流的使用及区别
JavaScript防抖和节流的使用及区别
727 154
|
缓存 JavaScript 中间件
优化Express.js应用程序性能:缓存策略、请求压缩和路由匹配
在开发Express.js应用时,采用合理的缓存策略、请求压缩及优化路由匹配可大幅提升性能。本文介绍如何利用`express.static`实现缓存、`compression`中间件压缩响应数据,并通过精确匹配、模块化路由及参数化路由提高路由处理效率,从而打造高效应用。
693 109
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
JavaScript
Node.js GET/POST请求
10月更文挑战第6天
267 2
Node.js GET/POST请求
|
前端开发 JavaScript UED
JavaScript 中的函数防抖与节流详解及实用场景
在前端开发中,处理用户频繁触发的事件,如输入框的输入、按钮点击、窗口调整大小等,常常需要优化性能以减少无效操作。为此,函数防抖(debounce)和函数节流(throttle)是两种常见的性能优化手段。本文将详细介绍两者的区别与实现,并探讨它们的应用场景。
891 1
|
JavaScript 前端开发 UED
JS 防抖与节流
防抖和节流是优化高频事件处理的技术。针对如`scroll`、`resize`等频繁触发的事件,它们能有效减少不必要的回调执行,节省资源。防抖确保在一段时间内仅执行最后一次操作,适用于输入框自动补全等场景;而节流则按固定间隔执行函数,适合拖拽、滚动事件。通过简单的JavaScript实现,可以显著提升应用性能和用户体验。
517 1
JS 防抖与节流
|
缓存 JavaScript CDN
一次js请求一般情况下有哪些地方会有缓存处理?
一次js请求一般情况下有哪些地方会有缓存处理?
263 4
|
JSON JavaScript 前端开发
js请求后端9
js请求后端9
191 2