页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<button id="btn">发送验证码</button>
</body>
<script>
const btn = document.getElementById("btn");
btn.onclick = function(){
console.log("已发送");
}
</script>
</html>
点击按钮时,点一次会在控制台在打印一次已发送.
假设每一次打印就是一次验证码请求,这样短信请求太多,现要求60s内只能请求一次验证码
按钮节流
const btn = document.getElementById("btn");
let flag = true;
if(flag){
btn.onclick = function(){
console.log("已发送");
this.innerHTML = "多次点击无效";
flag = false;
setTimeout(() => {
flag = true;
this.innerHTML = "发送验证码";
},60000)
}
}
60s后
函数调用节流
时间戳节流
一定时间内,只执行第一次,点击立即执行
//参数:要节流的函数,间隔时间
function a(fn,interval){
//定义上一次节流结束时间
let last = 0;
return function(){
//得到当前时间
let now = Date.now();
//当前时间 - 结束时间 > 间隔时间 执行函数
if(now - last >= interval){
fn.apply(this,arguments);
//重新赋值结束时间
last = now;
}
}
}
const btn = document.getElementById("btn");
function click(){
console.log("已发送");
}
const c = a(click,60000);
btn.onclick = c;
一直按按钮,60s内只会执行一次
定时器节流
一定时间内,只执行第一次,时间到后执行
function a(fn,interval){
let timer = null;
return function(){
let that = this;
let args = arguments;
if(!timer){
timer = setTimeout(() => {
fn.apply(that,args);
timer = null
},interval)
}
}
}
const btn = document.getElementById("btn");
function click(){
console.log("已发送");
}
const c = a(click,60000);
btn.onclick = c;
点击按钮后,结果一片空白,60s后执行函数,执行后再次点击重新进入60s等待
时间戳 + 定时器 节流
间隔时间内,点击立即执行一次,多次点击会记录最后一次点击
最后一次点击事件 + 间隔时间后执行一次
function a(fn,delay){
let timer = null;
let startTime = Date.now();
return function(){
//记录当前时间
let curTime = Date.now();
//记录运行时间
let remainning = delay - (curTime - startTime);
let that = this;
let args = arguments;
clearTimeout(timer);
//节流结束,一个新的节流函数走这里
if(remainning <= 0){
fn.apply(that,args);
startTime = Date.now();
}else {
//节流没结束,给最后一次调用绑定延迟
timer = setTimeout(fn,remainning);
}
}
}
const btn = document.getElementById("btn");
function click(){
console.log("已发送");
}
const c = a(click,60000);
btn.onclick = c;
60s内点击了四次,结果: