乐趣区

关于技术:不用防抖和节流用更底层的方式解决JS的重复请求

你或者在我的项目中遇到过这样的状况。成员 A 成员 B 都用得上一个后端接口 api,但它们相互不晓得对方什么时候申请这个接口,因而导致一关上页面,同一个接口居然反复申请了屡次。因为用户手抖,又因为成员遗记做申请的 loading 防误触解决,导致一个接口被用于疯狂申请,最终数据乱套,页面不可用。SPA 单页面利用,多个页面甚至是多个组件可能有同样的数据申请,齐全能够共享的数据却不得不反复申请,影响页面加载效率。想要用节流或者防抖解决下面的问题,然而后端返回数据的工夫浮动太大,导致不晓得应该设置多长的工夫。这些申请节约,实际上都有调用异步函数(async function)的参加的;因而,它们虽不是 async function 的问题,但却能够利用 async function 的特点来解决。async function 实质上是一个 Promise。因而只有利用好 Promise 的个性,就能解决这些问题。once-init 正是为解决这些问题而生。它从 Promise 的定义登程,用 Promise 的根底性能彻底地阻止了异步申请节约的产生。我用它做了两件事:缓存申请的返回值;缓存 Promise 申请自身;原理 once-init 的核心思想是缓存和执行队列;缓存返回值实现缓存返回值并不艰难,只有写一个单例模式就好了。上面是一个缓存的单例模式的简略示例;

如果缓存曾经有值,返回缓存的值;如果缓存没有值,执行异步函数;执行结束后,更新缓存;这是一个繁难的解决方案,它大略能解决 10% 的异步函数相干的问题,因为在第一次执行 Promise 实现之后,就不会再进行申请,也就不会产生节约了;然而,它没有解决多个 Promise 同时产生的状况。假如开发人员同一时间屡次调用 init,如果第一次调用的 Promise 还没有实现,cache 也还没有初始化,就会导致同一时间的所有调用仍旧创立新的 Promise。甚至有可能因为屡次申请,一直的变动 cache,你甚至没有方法确定最初 cache 的值是不是你最初一次申请的返回值。如果要解决这个问题,就须要利用 Promise 的个性,同一时间,同一个 async function,只容许同一个 Promise 处在 pending 状态。缓存 Promise 如果 Promise 正在执行,就不创立新的 Promise;间接返回正在执行的 Promise 的返回值;如果没有 Promise 正在执行,就创立并缓存新的 Promise;Promise 执行完结之后,删除缓存的 Promise;

通过这种形式,就能防止 promise 同一时间反复执行。这也是 once-init 这个库的核心思想。当然这个简略实现还有很多问题须要解决。​通过这种形式,就能防止 promise 同一时间反复执行。这也是 once-init 这个库的核心思想。

退出移动版