这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战
前言
前几天看到一本书叫做《javascript设计模式与开发实践》,翻了几篇发现写的非常不错,个人觉得挺对我的胃口。然后当我推荐给身边朋友的时候,他们说这个很早就看过了,一本比较经典的书了,好吧!!!!!! 我翻了几篇看到了几个新名词:分时函数、惰性加载函数。 但愿我不是最后知道的😂,接下来就总结一篇我看到的、学到的东西。
开始
分时函数
什么是分时函数呢?我觉得你可能在项目种也是用到过的,就是比如你需要新增1000个div到body, 这个时候直接绘制1000个div到body,其实浏览器是非常有压力的。 但是如果把这个1000个div用50m分批绘制,一批200个(10m), 那这个时候浏览器的压力就小了。 这个就是分时,那分时函数当然就是咱们把逻辑封装成函数了
代码实践:
//第一步先确定参数
//参数一 应该是数组(1000) Array
//参数二 应该是分批绘制的动作也就是个回调函数 Function
//参数三 应该是每次分批的绘制的量 Number
//参数四 应该是没批次绘制的时间(ms) Date
//结论函数应该是这个样的 timeChunk([], function() {}, 10, 1000)
/**
* @params { Array } ary
* @params { Function } fn
* @params { Number } count
* @params { Number } interval
*/
//第一步 先写分批绘制的函数start()
//condition 是咱们的count分批数量多少比如(100), Math.min(count || 1, ary.length)这个主要是兼容吧 怕ary的长度小了
//循环调用fn()回调, ary一直截取前一个
function timeChunk(ary, fn, count, interval) {
const start = function() {
let i = 0;
const condition = Math.min(count || 1, ary.length)
while (i < condition) {
let a = ary.shift();
fn(a);
i++;
}
}
}
//第二步:首次立刻调用
function timeChunk(ary, fn, count, interval) {
const start = function() {
let i = 0;
const condition = Math.min(count || 1, ary.length)
while (i < condition) {
let a = ary.shift();
fn(a);
i++;
}
}
//第一次立刻调用(第一批)
let firstTime = true;
return function() {
if(firstTime) {
start();
firstTime = false;
}
}
}
//第三步 然后再定时器分批次绘制(有点节流的感觉哈)我也是这个么觉得的
function timeChunk(ary, fn, count, interval) {
const start = function() {
let i = 0;
const condition = Math.min(count || 1, ary.length)
while (i < condition) {
let a = ary.shift();
fn(a);
i++;
}
}
//第一次立刻调用(第一批)
let firstTime = true, time;
return function() {
if(firstTime) {
start();
firstTime = false;
}
//写个定时器执行咱们的分批任务
time = setInterval(() => {
if(ary.length === 0) {
clearInterval(time);
}
start();
}, interval || 500)
}
}
//使用起来
let ary = new Array(100).fill(0);
const renderList = timeChunk(ary, function() {
console.log('我是timeChunk分批绘制函数平均每2秒绘制10次')
}, 10, 2000);
renderList();
防抖函数
什么是防抖函数呢? 就是在我多次触发的时候就执行我最后触发一次。这个样能大大减少不必要的性能,联动问题。 例如:我一个保存按钮用户一直再用鼠标点,这个时候在没做任何处理的情况下会多次触发保存事件。俩个解决方案:1、按钮loading,确定再第一次点了保存成功后才允许下次点击。2、添加防抖动事件,让用户随意点,程序就触发用户最后一次的动作。在选择2的时候就用到了咱们今天的防抖函数了。
代码实践:
//第一不从封装函数的角度出发,save就是咱们的按钮触发的事件:
let time;
function save() {
if(time) { clearTimeout(time) }
time = setTimeout(() => {
clearTimeout(time);
time = null;
console.log('我是保存按钮的事件')
}, 1000)
}
//上面就是一个简单的防抖的事件函数了。 大致就是在我一直点击save得时候一直清除定时器,最后一次才保留
//封装成一个通用的防抖函数
function debounce(fn, interval) {
let time;
return function() {
let args = arguments;
if(time) { clearTimeout(time) }
time = setTimeout(() => {
fn.apply(this, args)
clearTimeout(time)
time = null;
}, interval || 500)
}
}
//save按钮使用方式
const save = debounce(function() {
console.log('我是save函数添加了防抖事件')
//就可以再下面添加自己的逻辑了
}, 1000)
节流函数
节流函数跟防抖函数有区别嘛? 有!!!! 单从名称上就有区别。说一下节流函数:1、首次先调用一次;2、再多次触发的时间内比如30秒, 尼定义的节流函数是1秒 那么再尼连续点击的时间内会触发30次。这就是节流函数
代码实践:
//还是以保存按钮为例,给保存按钮添加节流事件
let time, firstTime = true;
function save() {
if(fistTime) {
console.log('我是save的节流事件,我首次触发立刻调用')
return firstTime = false;
}
if(time) return
time = setTimeout(() => {
clearTimeout(time);
time = null;
console.log('我是save的节流事件')
},1000)
}
//上面就是直接再save里面写的节流事件了
//那咱们封装下这个节流函数 搞成通用的
function throttle(fn, interval) {
let time, firstTime = true;
return function() {
const args = arguments;
const _m = this;
if(firstTime) {
fn.apply(_m, args)
return firstTime = false;
}
if(time) return
time = setTimeout(() => {
fn.apply(_m, args)
clearTimeout(time);
time = null;
}, interval || 500)
}
}
//给save 添加节流事件
const save = throttle(() => {
console.log('我是save的节流函数')
}, 1000)
惰性加载函数
什么是惰性加载函数呢? 就是优化咱们的经常调用的函数。但是为什么叫惰性加载呢?不理解!!!!!!(可能就是把一些不用加载或没必要做的判断抽象成不做,或者少做的)
代码实践:
//以书上的例子总结吧(没有想到更好的方案)浏览器的兼容
//未优化前
let addEvent = function(elem, type, handler) {
if(window.addEventListener) {
return elem.addEventListener(type, handler, false)
}
if(window.attachEvent) {
return elem.attachEvent(`on${type}`, handler)
}
}
//缺点:每次加载都需要进行判断进入里面的if条件
//第一次优化:
let addEvent = (function() {
if(window.addEventListener) {
return function() {
elem.addEventListener(type, handler, false)
}
}
if(window.attachEvent) {
return function() {
elem.attachEvent(`on${type}`, handler)
}
}
})();
//优化后的缺点是 平白无故先调用了下addEvent
//第二次优化就是咱们的惰性加载函数看看是什么样的
let addEvent = function(ele, type, handler) {
if(window.addEventListener) {
addEvent = function(ele, type, handler) {
ele.addEventListener(type, handler, false);
}
}else if(window.attachEvent) {
addEvent = function(ele, type, handler) {
ele.attachEvent(`on${type}`, handler)
}
}
addEvent(ele, type, handler);
}
//咱们大致分析下这个函数
//1、在使用的第一次判断了下
//2、直接更改了addEvent(这个时候的addEvent已经是判断后的了,在下次就不会在进行判断了)
//3、为什么在底部执行了一遍 addEvent(ele, type, handler)? 其实就是更改后的函数调用下,不能就返回一个函数。第一次没出发吧
总结
以上就是我对几种函数的理解
结束语
- 大家好 我是三原,多谢您的观看,我会更加努力(๑•̀ㅂ•́)و✧多多总结。
- 每个方法都是敲出来验证过通过的,有需要可以放心复制。
- 如果您给帮点个赞👍就更好了 谢谢您~~~~~
- 期待您的关注