详细分析JS函数去抖和节流_基础知识
这篇文章主要介绍了详细分析JS函数去抖和节流相关知识以及JS代码分析,对JS感兴趣的朋友学习参考下吧。
本篇内容从节流和去抖的概念基础知识讲起,对JS函数做了详细的分析,一起来看下:
1、什么是节流和去抖?
节流。就是拧紧水龙头让水少流一点,但是不是不让水流了。想象一下在现实生活中有时候我们需要接一桶水,接水的同时不想一直站在那等着,可能要离开一会去干一点别的事请,让水差不多流满一桶水的时候再回来,这个时候,不能把水龙头开的太大,不然还没回来水就已经满了,浪费了好多水,这时候就需要节流,让自己回来的时候水差不多满了。那在JS里有没有这种情况呢,典型的场景是图片懒加载监听页面的scoll事件,或者监听鼠标的mousemove事件,这些事件对应的处理方法相当于水,由于scroll和mousemove在鼠标移动的时候会被浏览器频繁的触发,会导致对应的事件也会被频繁的触发(水流的太快了),这样就会造成很大的浏览器资源开销,而且好多中间的处理是不必要的,这样就会造成浏览器卡顿的现象,这时候就需要节流,如何节流呢?我们无法做到让浏览器不去触发对应的事件,但是可以做到让处理事件的方法执行频率减少,从而减少对应的处理开销。
去抖。最早接触这个词应该是在高中物理里面学到的,有时候开关在在真正闭合之前可能会发生一些抖动现象,如果抖动的明显的话,对应的小灯泡可能会闪烁,把灯泡闪坏了不重要,万一把眼睛再给闪坏了可就麻烦了,这个时候就有去抖电路的出现。而在我们的页面里,也有这种情况,假设我们的一个输入框,输入内容的同时可能会去后台查询对应的联想 词,如果用户输入的同时,频繁的触发input事件,然后频繁的向后抬发送请,那么直到用户输入完成时,之前的请求都应该是多余的,假设网络慢一点,后台返回的数据比较慢,那么显示的联想词可能会出现频繁的变换,直到最后的一个请求返回。这个时候就可以在一定时间内监听是否再次输入,如果没有再次输入则认为本次输入完成,发送请求,否则就是判定用户仍在输入,不发送请求。
去抖和节流是不同的,因为节流虽然中间的处理函数被限制了,但是只是减少了频率,而去抖则把中间的处理函数全部过滤掉了,只执行规判定时间内的最后一个事件。
2、JS实现。
前面BB了这么多,感谢你耐心的看到这里,接下来我们来自己动手看看如何实现节流和去抖。
节流:
/** 实现思路: ** 参数需要一个执行的频率,和一个对应的处理函数, ** 内部需要一个lastTime 变量记录上一次执行的时间 **/ function throttle (func, wait) { let lastTime = null // 为了避免每次调用lastTime都被清空,利用js的闭包返回一个function确保不生命全局变量也可以 return function () { let now = new Date() // 如果上次执行的时间和这次触发的时间大于一个执行周期,则执行 if (now - lastTime - wait > 0) { func() lastTime = now } } }
再看如何调用:
// 由于闭包的存在,调用会不一样 let throttleRun = throttle(() => { console.log(123) }, 400) window.addEventListener('scroll', throttleRun)
这时候f疯狂的滚动页面,会发现会400ms打印一个123,而没有节流的话会不断地打印, 你可以改变wait参数去感受下不同。
但是到这里,我们的节流方法是不完善的,因为我们的方法没有获取事件发生时的this对象,而且由于我们的方法简单粗暴的通过判断这次触发的时间和上次执行时间的间隔来决定是否执行回调,这样就会造成最后一次触发无法执行,或者用户出发的间隔确实很短,也无法执行,造成了误杀,所以需要对方法进行完善。
function throttle (func, wait) { let lastTime = null let timeout return function () { let context = this let now = new Date() // 如果上次执行的时间和这次触发的时间大于一个执行周期,则执行 if (now - lastTime - wait > 0) { // 如果之前有了定时任务则清除 if (timeout) { clearTimeout(timeout) timeout = null } func.apply(context, arguments) lastTime = now } else if (!timeout) { timeout = setTimeout(() => { // 改变执行上下文环境 func.apply(context, arguments) }, wait) } } }
这样我们的方法就相对完善了,调用方法和之前相同。
去抖:
去抖的方法,和节流思路一致,但是只有在抖动被判定结束后,方法才会得到执行。
debounce (func, wait) { let lastTime = null let timeout return function () { let context = this let now = new Date() // 判定不是一次抖动 if (now - lastTime - wait > 0) { setTimeout(() => { func.apply(context, arguments) }, wait) } else { if (timeout) { clearTimeout(timeout) timeout = null } timeout = setTimeout(() => { func.apply(context, arguments) }, wait) } // 注意这里lastTime是上次的触发时间 lastTime = now } }
这时候按照之前同样的方式调用,会发现无论怎么疯狂的滚动窗口,只有停止滚动时,才会执行对应的事件。
去抖和节流已经有很多成熟的js进行了实现,其大致思路基本是这样的。
我们再给大家分享一下网友的实现方法的代码:
方法一
1.这种实现方式的思路很好理解:设置一个一间隔时间,比如50毫秒,以此时间为基准设置定时器,当第一次触发事件到第二次触发事件间隔小于50毫秒时,清除这个定时器,并设置一个新的定时器,以此类推,直到有一次事件触发后50毫秒内没有重复触发。代码如下:
function debounce(method){ clearTimeout(method.timer); method.timer=setTimeout(function(){ method(); },50); }
这种设计方式有一个问题:本来应该多次触发的事件,可能最终只会发生一次。具体来说,一个循序渐进的滚动事件,如果用户滚动太快速,或者程序设置的函数节流间隔时间太长,那么最终滚动事件会呈现为一个很突然的跳跃事件,中间过程都被节流截掉了。这个例子举的有点夸张了,不过使用这种方式进行节流最终是会明显感受到程序比不节流的时候“更突兀”,这对于用户体验是很差的。有一种弥补这种缺陷的设计思路。
方法二
2.第二种实现方式的思路与第一种稍有差别:设置一个间隔时间,比如50毫秒,以此时间为基准稳定分隔事件触发情况,也就是说100毫秒内连续触发多次事件,也只会按照50毫秒一次稳定分隔执行。代码如下:
var oldTime=new Date().getTime(); var delay=50; function throttle1(method){ var curTime=new Date().getTime(); if(curTime-oldTime>=delay){ oldTime=curTime; method(); } }
相比于第一种方法,第二种方法也许会比第一种方法执行更多次(有时候意味着更多次请求后台,即更多的流量),但是却很好的解决了第一种方法清除中间过程的缺陷。因此在具体场景应根据情况择优决定使用哪种方法。
对于方法二,我们再提供另一种同样功能的写法:
var timer=undefined,delay=50; function throttle2(method){ if(timer){ return ; } method(); timer=setTimeout(function(){ timer=undefined; },delay); }
以上就是本文的所有内容,希望会给大家带来帮助!!
相关推荐:
Atas ialah kandungan terperinci 详细分析JS函数去抖和节流_基础知识. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Pengenalan kepada cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata: Dengan populariti Internet dan kemajuan teknologi, semakin banyak restoran telah mula menyediakan perkhidmatan pesanan dalam talian. Untuk melaksanakan sistem pesanan dalam talian masa nyata, kami boleh menggunakan teknologi JavaScript dan WebSocket. WebSocket ialah protokol komunikasi dupleks penuh berdasarkan protokol TCP, yang boleh merealisasikan komunikasi dua hala masa nyata antara pelanggan dan pelayan. Dalam sistem pesanan dalam talian masa nyata, apabila pengguna memilih hidangan dan membuat pesanan

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian Dalam era digital hari ini, semakin banyak perniagaan dan perkhidmatan perlu menyediakan fungsi tempahan dalam talian. Adalah penting untuk melaksanakan sistem tempahan dalam talian yang cekap dan masa nyata. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian dan memberikan contoh kod khusus. 1. Apakah itu WebSocket? WebSocket ialah kaedah dupleks penuh pada sambungan TCP tunggal.

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

Penggunaan: Dalam JavaScript, kaedah insertBefore() digunakan untuk memasukkan nod baharu dalam pepohon DOM. Kaedah ini memerlukan dua parameter: nod baharu untuk dimasukkan dan nod rujukan (iaitu nod di mana nod baharu akan dimasukkan).

JavaScript ialah bahasa pengaturcaraan yang digunakan secara meluas dalam pembangunan web, manakala WebSocket ialah protokol rangkaian yang digunakan untuk komunikasi masa nyata. Menggabungkan fungsi berkuasa kedua-duanya, kami boleh mencipta sistem pemprosesan imej masa nyata yang cekap. Artikel ini akan memperkenalkan cara untuk melaksanakan sistem ini menggunakan JavaScript dan WebSocket, dan memberikan contoh kod khusus. Pertama, kita perlu menjelaskan keperluan dan matlamat sistem pemprosesan imej masa nyata. Katakan kita mempunyai peranti kamera yang boleh mengumpul data imej masa nyata
