【深入JavaScript_笔记一_防抖与节流】

news/2024/7/19 16:23:45 标签: js, javascript, 运维

目录

    • 前言
    • 正文内容
      • 防抖
        • 非立即执行方式
        • 立即执行方式
      • 节流
        • 时间戳节流
        • 定时器节流
      • 防抖和节流的区别
    • 总结

前言

在前段日子,在内心的逼迫下跟着众多大佬的脚步,磨磨蹭蹭慢慢悠悠的学完了一些原生JavaScript底层的知识。产生了很多感触,编程技术太多了,写得出东西不代表真的掌握了,而理解一项技术的底层原理更加重要,只有了解了整个运行的过程,才能分析调优或者创新新的框架。

本来打算先学习点别的,但是思索之后,还是决定顺带着继续一点点磨 JavaScript,毕竟这东西真的很重要。

正文内容

原来在写作业时,比较注重的只有程序功能是否实现,对于效率确实很少考虑,但是愈发深入的学习
让我了解到每一项成熟的技术最后都要走向商用或者应用场景变得非常大型,那么每一次运行程序的成本就要尽量压低,一次响应节省1s,那么10000次相应就会节约出快三个小时,所以对于效率的考虑我们应该作为一种编程习惯与思想,融入写代码的过程中。

防抖

那么什么是防抖呢(通俗的说就是你越急我越不让你执行,乖乖等着是最快的办法),上学期在嵌入式设计这门课中有学过这个概念。通俗的说就是因为你的按钮没有设置相关检测程序,以至于在人为按动之后,无意间的震动,系统也会进行响应,从而执行很多遍按钮事件。

那JavaScript里的防抖自然也是这个意思,比如 ajax函数,如果不能很好地设置极短时间内次数拦截,那么将会给后台造成很大压力,比如。

这里在网页里写了个div进行测试

<div id="content"
     style="height:150px;background-color:#ccc;font-size:80px;"></div>

这是模拟与后台通信的方法

javascript">    let content = document.getElementById('content');

    function count() {
        console.log("向后台发送请求!")
    }

    content.onmousemove = count;	//绑定鼠标移动事件

结果

可以清楚的看到,如果我们没有采取任何措施,那么将存在短时间访问急剧增加的风险,如果每一次请求的代码执行量都很大,要经过复杂的算法和计算,那这样就很可能导致服务器宕机。于是们更改一下代码。

通过查资料我们知道了防抖函数有两种,非立即执行和立即执行。

非立即执行方式

这种方式的意思是触发事件后函数不会立即执行,只会在最后一次触发事件后等待设定的wait时间结束时执行一次

<div id="content"
     style="height:150px;background-color:#ccc;font-size:80px;"></div>
javascript">    let content = document.getElementById('content');

    function count() {
        console.log("向后台发送请求!!!!!")
    }

    // 非立即执行版
    function debounce(func, wait) {
        let timer;
        return function () {
            console.log("触发页面事件")
            if (timer) clearTimeout(timer);
            timer = setTimeout(func, wait)
        }
    }


    content.onmousemove = debounce(count, 1000);

可以清楚地看到事件触发了很多次,但是经过等待只执行了一次func,事件触发时先等待完成再进行函数func的执行。
结果

立即执行方式

接下来我们看看立即执行的版本
这种方式的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果

<div id="content"
     style="height:150px;background-color:#ccc;font-size:80px;"></div>
javascript">	let content = document.getElementById('content');

    function count() {
        console.log("向后台发送请求!!!!!")
    }
    
    // 立即执行版
    function debounce(func, wait) {
        let timer;
        return function () {
            if (timer) clearTimeout(timer);
            let callNow = !timer;

            timer = setTimeout(() => {
                timer = null;
            }, wait)

            if (callNow) func();
        }
    }

	content.onmousemove = debounce(count, 1000);

可以看到立即执行的方式是先执行再等待,这里引用了一个中间变量 callNow,来判断执行完一次func之后是否已经完成等待,一旦完成,就会把时间对象timer变为null,也就预示着下一次事件触发时callNow的值会变成true,就可以执行函数fun
结果

节流

先把定义拉上来:指连续触发事件但是在 n 秒中只执行一次函数。
同样有两个版本,时间戳和定时器版。

时间戳节流

这种方式是利用每个时刻与上个时刻的时间差来判断是否达到等待时长。

javascript">    let content = document.getElementById('content');

    function count() {
        console.log("向后台发送请求!!!!!")
    }

    // 时间戳版
    function throttle(func, wait) {
        let previous = 0;

        return function () {
            let now = Date.now();//返回自1970年1月1日 00:00:00到当前时间的毫秒数。
            if (now - previous > wait) {
                func();
                previous = now;
            }
        }
    }

    content.onmousemove = throttle(count, 1000);

我们可以清晰地看到节流是固定每1s执行一次,在这段代码中,我们通过取时间差来判断等待时间是否达到了 1000ms,进而判断是否可以执行函数 func
结果

定时器节流

这种方式利用setTimeout实现两个操作同时进行(标识符timeout赋值和执行函数func),从而达到节流的目的。

javascript">    let content = document.getElementById('content');

    function count() {
        console.log("向后台发送请求!!!!!")
    }

    // 定时器版
    function throttle(func, wait) {
        let timeout;
        return function () {
            console.log(timeout)
            if (!timeout) {
                timeout = setTimeout(() => {
                    timeout = null;
                    func()
                }, wait)
            }
            console.log("-------")
        }
    }

    content.onmousemove = throttle(count, 1000);

timeout作为标志符,再等待时间结束前,他是一直具有值的,所以不会执行判断语句内部的语句。

结果

防抖和节流的区别

防抖动是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行。

总结

防抖动:触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间

举例:登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖

非立即执行方式: 高频触发事件-----等待指定时间-----执行一次-----下一次触发事件-----(循环往复)
立即执行方式: 高频触发事件-----执行一次-----等待指定时间-----下一次触发事件-----(循环往复)

节流:高频事件触发,但在 n 秒内只会执行一次,所以节流会稀释函数的执行频率

举例:浏览器播放事件,每个一秒计算一次进度信息

高频触发事件-----(固定的等待时长)-----执行一次-----继续保持触发事件-----(固定的等待时长)-----(循环往复)


http://www.niftyadmin.cn/n/644314.html

相关文章

最近的学习---一句话收获(备查用)(2)

1.在内核中分配大内存问题。 首先要明白内核没有义务为你分配连续的物理内存&#xff0c;因此你需要的内核中连续的物理内存就是苛刻的要求&#xff0c;既然在计算机系统抽象给用户一个连续的美丽的一维的虚拟内存&#xff0c;那么任何时候计算机都没有义务让你看到物理内存&am…

【懒狗福音】平板 to 扩展屏 有效提高生产力

目录前言正文下载软件运行软件实际操作总结前言 为了下学期自己可以提高一些效率&#xff0c;最进入了个华为的平板&#xff0c;matepad10.8&#xff0c;打算进入一波无纸化学习。&#xff08;主要是懒&#xff0c;不想整天背着专业书和电脑跑这跑那&#xff09;&#xff0c;东…

C++动态数组的作用

假如要创建一个数组&#xff0c;数组长度由用户输入 那就可以这样写&#xff1a; int bufferSize; cin>>bufferSize; int *pnew int[bufferSize]; 但是&#xff0c;如果用静态数组实现这个功能请问怎么实现&#xff1f; int bufferSize; cin>>bufferSize; int arr[…

【闲暇时间整活】给 Windows 命令行窗口 “改头换面”

目录前言正文内容安装软件自定义样式自定义设置主题设置背景图片总结前言 也快要到开学的日子了&#xff0c;是时候整理一下东西准备迎接新学期了&#xff0c;整理归类进行时。 看看桌面&#xff0c;嗯不错&#xff0c;简单干净&#xff08;利用双击隐藏程序&#xff0c;中间狗…

ca32a_demo_c++创建动态数组

/* ca32a_demo_c创建动态数组20200127 静态是在堆栈上创建的&#xff0c;动态实在堆&#xff08;heap&#xff09;上创建的 堆&#xff08;heap&#xff09;-自由存储区&#xff08;free store&#xff09;-内存的一个区域 c语言&#xff1a;malloc创建和free释放 c语言&#x…

Nginx配置实战

一、基于域名虚拟主机配置 1、修改nginx.conf配置文件 [rootlinux-node2 ~]# cat /etc/nginx/nginx.conf worker_processes auto; error_log /var/log/nginx/error.log; events {worker_connections 1024; } http {include mime.types;default_type application/octet…

【良心好物】SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

目录前言正文内容结束前言 找一个适合自己的网课可太难了&#xff01;&#xff01; 于是记录一下&#xff0c;对比过某些付费课程&#xff0c;对于个人来说的确更适合这个&#xff01; 放在这里&#xff0c;有需要的兄弟可以看看&#xff0c;不要再被看的难受的课折磨了&#…

ca33a_demo_c++_新旧代码的兼容char数组与vector_string相互转换

/*ca33a_demo_c33_CppPrimer_新旧代码的兼容_txwtech 旧代码&#xff1a;数组和c风格字符串 新代码&#xff1a;vector和string 相互转换&#xff1a; c风格字符串<- ->string 数组<- ->vector C3867错误。https://docs.microsoft.com/zh-cn/cpp/error-messages/c…