利用闭包与高阶函数实现缓存函数的创建&&缓存函数在项目中的性能优化

这篇具有很好参考价值的文章主要介绍了利用闭包与高阶函数实现缓存函数的创建&&缓存函数在项目中的性能优化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

利用闭包与高阶函数实现缓存函数的创建

缓存函数是一种用于存储和重复利用计算结果的机制。其基本思想是,当一个函数被调用并计算出结果时,将该结果存储在某种数据结构中 (通常是一个缓存对象)以备将来使用。当相同的输入参数再次传递给函数时,不再执行实际的计算,而是直接返回之前缓存的结果,从而避免重复的耗时计算。

缓存函数避免重复计算、目的是提高性能、数据结构存储

缓存一般是以键值对的形势存储在数据的结构当中,其中的键是函数的输入参数,而值就是对应的输出结果

应用场景:在web网站开发当中网络请求,数学计算,或者是大量花费时间的一个操作,那么在JavaScrip中可以使用object对象来实现缓存。

示例:以下当前函数调用了几次,就执行了几次,且传入的参数一样,那么输出的结果都是同一个结果。

function expensiveCalculation(input){
    console.log("执行昂贵计算...")
    return input * 2;
}
expensiveCalculation(10)
expensiveCalculation(10)
expensiveCalculation(10)
expensiveCalculation(10)
expensiveCalculation(10)

我们为什么需要花费嫩么多时间去执行此函数呢,这就是我们缓存函数的需求点。

我们可以利用什么方式进行目标的达成呢?有两大类。

什么是闭包:

允许函数保留其包含(封闭)范围中变量的访问权,即使在该范围外执行函数

闭包是一种在函数嵌套的情况下,内部函数可以访问外部函数作用域中变量的现象。基本上,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包允许你从一个函数中返回另一个函数,并且在后者执行时仍然能够访问前者的变量。

通俗地说,闭包是由函数和与其相关的引用环境组合而成的实体。它可以让函数访问在它被创建时所处的词法作用域中的变量,即使函数在这个词法作用域外执行,也能够访问这些变量。

闭包的基本特点是:

  • 内部函数可以访问外部函数中的变量和参数。
  • 外部函数执行完毕后,其作用域链不会被销毁,因为内部函数持有对其的引用。
  • 外部函数中的变量和参数在内部函数被引用时,会被保存在堆内存中,而不是在栈内存中,因此内部函数可以访问它们。

闭包常常用于解决 JavaScript 中的作用域问题、封装变量、模块化代码等方面,同时也会因为滥用而导致内存泄漏等问题。因此,在使用闭包的过程中需要谨慎操作。

什么是高阶函数:

接受函数作为参数或将函数作为返回值输出的函数

高阶函数的特点:

  1. 接受函数作为参数:高阶函数可以接受一个或多个函数作为参数,这样可以灵活地传递不同的行为和逻辑给函数。

  2. 返回函数:高阶函数可以返回一个新的函数,这样可以延迟执行、构造闭包、创建函数工厂等。

那么根据闭包和高阶函数,我们可以使用以下代码去实现缓存函数

参数是一个函数,且函数将会返回一个闭包函数,且会保留originalFunction和cache两个内容变量的访问权,所以会产生一个闭包的概念,并且参数和返回值都是一个函数,所以它进行的是高阶函数的一个操作。以下我们判断的是arg参数是否存在于函数当中,如果存在,则直接利用缓存返回值进行结果的返回,如果不存在,则使用原始函数的调用进行的返回,将其结果值进行缓存的处理。

定义一个createCachedFunction函数,它接受一个原始函数作为参数,并返回一个闭包函数。闭包函数中使用一个缓存对象cache来存储计算结果。当闭包函数被调用时,首先检查参数是否存在于缓存中,如果存在,则直接返回缓存中的结果;如果不存在,则调用原始函数进行计算,并将结果存入缓存中后返回。这样,每次调用闭包函数时,都会先检查缓存,避免重复计算。 

//originalFunction是一个原始的函数
function createCachedFunction(originalFunction){
     //定义一个对象进行缓存数据的存储,cache用来计算先前的结果值
    const cache = {}
    return function(arg){
        //判断是否存在,存在则从缓存中获取
        if(cache[arg]){
            console.log(cache,arg)
            console.log('从缓存中取值',cache[arg])
            return cache[arg]
        }
        //如果是第一次执行,那么则将结果值放在result
        const result = originalFunction(arg)
        cache[arg] = result
        console.log("执行昂贵计算...",result)
        return result
    }
}
 
function expensiveCalculation(input){
    console.log("执行昂贵计算...")
    return input * 2;
}
 
//调用createCachedFunction函数
const cachedExpensiveCalculation = 
    createCachedFunction(expensiveCalculation)
 
 
cachedExpensiveCalculation(10)
cachedExpensiveCalculation(10)
cachedExpensiveCalculation(10)
cachedExpensiveCalculation(10)
cachedExpensiveCalculation(10)

以下则是输出的结果:

利用闭包与高阶函数实现缓存函数的创建&&缓存函数在项目中的性能优化,缓存

上述代码通过调用 createCachedFunction 函数创建了一个带有缓存功能的函数cachedExpensiveCalculation。它接收一个输入参数,并在内部使用 originalFunction 进行昂贵的计算。首次调用时,会执行昂贵的计算并将结果存储在 cache 对象中,后续再次调用时会直接从缓存中获取结果
在示例中,我们调用了 cachedExpensiveCalculation(10) 多次,但只有第一次会执行昂贵的计算,后续调用都会从缓存中获取之前的结果。这样可以避免重复计算,提高程序的性能。

缓存函数在项目中的性能优化

比如在请求操作,对请求操作进行性能优化

我们在界面当中,设置一个按钮,假设id为fetchButton,叫做获取数据

除了按钮,我们还给div进行相应的结果展示

那么在准备这两个内容以后,我们可以尝试定义数据请求的函数,请求内容是从服务器当中进行一个获取,传递一个参数,在进行fetch请求,传入地址信息,将参数id一并传入,在获取到了以后.then的方式进行response数据内容放回,最终返回response.json()数据。

<body>
    <h1>缓存函数在项目中的性能优化</h1>
    <button id="fetchButton">获取数据</button>
    <div id="resultContainer"></div>
    <script>
        function fetchDataFromServer(postId){
            console.log("从服务器端获取数据:",postId);
            return fetch(
                `https://jsonplaceholder.typicode.com/posts/${postId}`
            ).then(( response) => response.json());
        }

        const fetchButton = document.getElementById("fetchButton");
        const resultContainer = document.getElementById("resultContainer");

        fetchButton.addEventListener("click",() => {
            const postId = Math.floor(Math.random() * 5) + 1;
            fetchDataFromServer(postId);
        });
    </script>
</body>

当我们触发按钮进行数据请求,每次传入相同的参数,依旧会重复请求,浪费网络带宽的资源,那么这时候需要思考,如果相同参数进行请求,请求后再次请求是否可以直接从缓存中直接获取呢,因此就可以用到之前我们用到的缓存函数的定义。

function createCachedFunction(originalFunction){
    const cache = {};
    return function(arg){
        if(cache[arg]){
            console.log("从缓存中进行数据获取:",arg);
            return Promise.resolve(cache[arg]);
        }

        //如果是第一次执行,那么则将结果值放在result
        return originalFunction(arg).then(result=>{
            cache[arg] = result;
            console.log("d第一次进行数据获取,并实现缓存",arg)
            return result
        });
    };
}

const cachedFetchData = createCachedFunction(fetchDataFromServer);

const fetchButton = document.getElementById("fetchButton");
const resultContainer = document.getElementById("resultContainer");

fetchButton.addEventListener("click",() => {
    const postId = Math.floor(Math.random() * 5) + 1;
    cachedFetchData(postId).then(data => {
        resultContainer.innerHTML = `<pre>${JSON.stringify(
            data,
            null,
            2
        )}</pre>`
});

以下则是输出的结果:

利用闭包与高阶函数实现缓存函数的创建&&缓存函数在项目中的性能优化,缓存

同一参数第一次进行请求,是从远程服务器中获取,但是当我们下一次参数相同时,就从缓存中进行获取。请求不会重复触发,这样子就完成了缓存函数在项目中请求时的性能优化最终实现。文章来源地址https://www.toymoban.com/news/detail-773170.html

到了这里,关于利用闭包与高阶函数实现缓存函数的创建&&缓存函数在项目中的性能优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【Rust】Rust学习 第十三章Rust 中的函数式语言功能:迭代器与闭包

    【Rust】Rust学习 第十三章Rust 中的函数式语言功能:迭代器与闭包

    Rust 的设计灵感来源于很多现存的语言和技术。其中一个显著的影响就是  函数式编程 ( functional programming )。函数式编程风格通常包含将函数作为参数值或其他函数的返回值、将函数赋值给变量以供之后执行等等。 更具体的,我们将要涉及: 闭包 ( Closures ),一个可以储

    2024年02月12日
    浏览(15)
  • 一种基于闭包函数实现自动化框架断言组件的设计实践

    目前测试组同学基本具备自动化脚本编写能力,为了提高效率,如何灵活运用这些维护的脚本去替代部分手工的重复工作?为了达到测试过程中更多的去使用自动化方式,如何能够保证通过脚本覆盖更多的校验点,提高自动化测试的精度和力度?那么一定是不断的丰富断言,

    2024年02月08日
    浏览(12)
  • 高阶C语言|字符函数和字符串函数--函数的模拟实现

    高阶C语言|字符函数和字符串函数--函数的模拟实现

    C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串 中或者 字符数组 中。 字符串常量 适用于那些对它不做修改的字符串函数 size_t代表strlen函数返回的是一个无符号整形,str指向的是字符串,接收字符串的地址 字符串已

    2024年02月16日
    浏览(14)
  • vue写法——使用js高阶函数实现多条件搜索功能

    vue写法——使用js高阶函数实现多条件搜索功能

    🙂博主:小猫娃来啦 🙂本文核心: vue封装——使用js高阶函数实现多条件搜索功能 之前出过一个react写法的前端搜索(react写法——使用js高阶函数实现多条件搜索功能) 今天我们再研究一下vue中怎么实现。 react和vue有什么区别? 这个区别要细说可太多了,但是最终都能归

    2024年02月11日
    浏览(10)
  • 03.利用Redis实现缓存功能---解决缓存穿透版

    03.利用Redis实现缓存功能---解决缓存穿透版

    提示:学习如何利用Redis实现添加缓存功能解决缓存穿透版 缓存穿透讲解图 : 解决方案: 采用缓存空对象 采用布隆过滤器 解决方案流程图 : 1. 准备pom环境 2. 配置ThreadLocal和过滤器 3. Controller层:负责接收请求和向下分配 4. Service层:负责业务的处理逻辑

    2024年02月14日
    浏览(7)
  • 04.利用Redis国逻辑过期实现缓存功能---解决缓存击穿

    04.利用Redis国逻辑过期实现缓存功能---解决缓存击穿

    提示:学习如何利用Redis逻辑过期实现添加缓存功能解决缓存击穿 缓存击穿讲解图 : 解决方案: 采用互斥锁 采用逻辑过期 1. 准备pom环境 2. 配置ThreadLocal和过滤器 3. RedisData接收数据 3. Controller层:负责接收请求和向下分配 4. Service层:负责业务的处理逻辑

    2024年02月13日
    浏览(29)
  • 利用Vue命令行快速创建项目案例

    利用Vue命令行快速创建项目案例

    今天特意写了一篇关于如何利用Vue命令行快速创建项目案例,希望对大家有帮助,首先需要环境要求:安装有  Node.js 、  vue 、  vue-cli   安装有 Node.js、 vue、 vue-cli (node下载地址: https://nodejs.org/en/),打开cmd,查看nodejs版本和npm版本,在命令行中输入: node -v //node版本

    2024年01月20日
    浏览(8)
  • 利用VSCode创建前端vue项目,详细步骤

    利用VSCode创建前端vue项目,详细步骤

    1.先创建项目需要放置的文件夹,打开VSCode 2.输入终端指令:vue create wms-web,回车即可创建 3.跳出vue版本选择,根据需要选择版本,这里选择vue2,然后回车 4.等待创建完成… 5.创建成功后,最后显示两行命令:cd wms-web,npm run serve 6.根据命令输入cd wms-web,进入wms-web项目,输入

    2024年04月14日
    浏览(10)
  • 如何利用Idea创建一个Servlet项目(新手向)

    如何利用Idea创建一个Servlet项目(新手向)

    💕\\\"Echo\\\"💕 作者:Mylvzi 文章主要内容:如何利用Idea创建一个Servlet项目(新手向) Servlet是tomcat的api,利用Servlet进行webapp开发很方便,本文将介绍如何通过Idea创建一个Servlet项目(一共分为七步,这可能是我们写过的最复杂的 hello world) 在项目创建的过程中,我们将使用maven进行代码的编

    2024年02月19日
    浏览(8)
  • 面试—如何介绍项目中的多级缓存?

    面试—如何介绍项目中的多级缓存?

    项目中使用的多级缓存也就是 分布式缓存 Redis + 本地缓存 Caffeine ,那么令 Caffeine 作为一级缓存,Redis 作为二级缓存,在项目中通过记录数据的访问次数,将热点数据放在 本地缓存 ,将非热点数据放在 Redis缓存 中,访问流程如下: 使用多级缓存的好处 在于 Redis 单机每秒可

    2024年02月05日
    浏览(15)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包