在JavaScript中,我们很常见的是需要掌握过程抽象的思想。对于过程抽象,是函数式编程思想的应用。而 高阶函数(HOF) 便是过程抽象的体现之一。
接下来我们就来一起学习一下常见的高阶函数。
Once
在一些场景下,我们可能会遇到这样的需求,我们做了一个报名页面,然后需要用户提交报名成功的个人信息,但是用户可能会因为手抖,或者是一些网络的卡顿之类的原因,造成了用户在短时间内大量点击提交按钮,这时候可能会突然出现很多用户提交的相同的信息,为了避免这种情况,我们可以在前端做出一定的优化。
我们可以利用这样的高阶函数来完成优化:
function once(fn){
return function(...args){
if(fn){
const ret = fn.apply(this,args);
fn = null;
return ret;
}
}
}
结合上面的"公式",我们可以写出只能点击一次的提交按钮了。
function once(fn){
return function(...args){
if(fn){
const ret = fn.apply(this,args);
fn = null;
return ret;
}
}
}
const commit = once(function CommitFun(username,password) {
if(username !== "" && password !== "") {
// ...这里是提交代码
console.log("提交了一次");
}
});
commit("abc","123456");
commit("abc","123456");
我们模拟一下表单提交的场景,在nodejs上执行一下,打印的结果如下:
分析一下上面的结果,我们模拟了用户提交了两次的场景,不过我们查看控制台,发现只有一次提交结果,说明我们的只能点击一次的高阶函数封装的没有问题,再看一下源码,我们的Once函数是讲函数作为参数传递到once中去,第一次提交的时候if没什么问题,而后续的操作中,因为fn的值为null,高阶函数不会返回,所以不会提交。
节流
我们再看一个节流的例子
现在我们的场景变了,假如我们在做一个整点秒杀活动.我们要如何做呢?不做任何限制的话,流量等资源开销过大,这时候我们就要考虑到节流,比如秒杀抢购按钮,我们不限制他的点击次数,但是我们可以对他做一个节流的操作,让他事件每次触发间隔50ms之类的.
看一下节流的高阶函数
function throttle(fn,time = 500){
let timer;
return function(...args){
if(timer == null){
fn.apply(this,args);
timer = setTimeout(()=>{
timer = null;
},time);
}
}
}
防抖
想象一下这个场景:我们要开发一个自动保存功能的网页版的ide,不断地自动保存开销过大,我们希望用户不再操作500ms后,自动保存的网页版ide,我们可以设置防抖,在用户不再操做500ms后,触发保存事件。
let timer;
return function(...args){
clearTimeout(timer);
timer = setTimeout(()=>{
fn.apply(this,args);
},dur);
}
}