惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
量子位
月光博客
月光博客
罗磊的独立博客
宝玉的分享
宝玉的分享
博客园_首页
酷 壳 – CoolShell
酷 壳 – CoolShell
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
WordPress大学
WordPress大学
博客园 - 叶小钗
博客园 - 聂微东
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
雷峰网
雷峰网
博客园 - 三生石上(FineUI控件)
Jina AI
Jina AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - Franky
美团技术团队
爱范儿
爱范儿
V
Visual Studio Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Y
Y Combinator Blog

Aimee's Blog

秒杀怎么防机器人:验证码之外的几道防线 防薅羊毛怎么做:号码风控、设备指纹与分层策略 接口限流怎么选:固定窗口、滑动窗口、令牌桶 批量打包下载怎么设计:流式 ZIP 与异步任务 图片处理怎么做:异步处理与 CDN 实时参数 大文件上传怎么设计:分片、断点续传、秒传 报表可重跑的设计:快照、水位线与幂等 UV 统计为什么有误差:精确计数与近似计数怎么选 大数据量导出怎么做:流式写入与异步任务 排行榜的两类需求,难度差了一个数量级 内容审核怎么选:先审后发,还是先发后审 实时热榜怎么设计:Redis ZSet 与热度分值 互关状态怎么保持同步:双向关系的维护与缓存失效 并发点赞的计数设计:原子操作与最终对账 删了父评论,子评论怎么处理——先想清楚用户看到的是什么 定时消息任务触发了两次 消息量大,写扩散还是读扩散——接到这个需求先问清楚规模 同一条消息推送了三次 活动结束了,用户还在收短信 接到注销需求,先问两个问题 微服务与服务拆分:何时拆、怎么拆 异步与事件驱动架构:把协作从「打电话」改成「发消息」 高可用设计:怎么让系统尽量不宕机 可扩展性设计:怎么让系统加机器就能扛更多 缓存架构:多级缓存怎么搭 高并发三板斧:限流、熔断、降级 架构设计到底在设计什么 —— 从单体到微服务的演进 服务成本账:一个服务一个月烧多少钱 可观测性:线上出问题怎么查 API 设计:好接口长什么样
防抖和节流
Aimee · 2021-10-26 · via Aimee's Blog

防抖

触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。 每次触发事件时都取消之前的延时调用方法 ​

常见使用场景是:用户输入,只有在输入完之后才做校验 ​

示例: 滚动结束后才执行一次

function debounce(fun, wait, imediate){
	let timer = null
  return function(...rest){
    if(imediate&&!timer) {
    	fun.apply(this,rest)
    }
  	if(timer)clearTimeout(timer)
    timer = setTimeout(()=>{
      fun.apply(this,rest)
    }, wait)
  }
}
const fun = function(...rest){
  console.log(new Date().getTime())
}
window.addEventListener('scroll',debounce(fun,1000,false))

过程:

  • 设置一个外层函数,接受需要执行的函数、等待时间、是否立刻执行参数,定义一个变量timer共内层函数使用
  • 外层函数return 一个函数,该函数中通过外层变量timer记录定时器,在设置定时器之前先判断是否是立刻执行并且没有定时器存在,满足则直接调用需要执行的函数;再判断定时器是否存在,如果存在清除定时器,设置定时器,定时器的回调为需要执行的函数,时间参数为等待的时间参数

节流

高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。 每次触发事件时都判断当前是否有等待执行的延时函数 ​

常见使用场景是页面滚动,或者鼠标移动,减少函数调用的频次。 ​

示例: 滚动开始后每间隔1000ms执行一次

// 时间戳版本 

function throttle(fun, time){
	let last = 0;
  return function(...rest){
  	let now = new Date().getTime();
    if(now-last>time){
    	last = now;
      fun.apply(this, rest)
    }
  }
}
// 定时器版本
function throttle2(fun, time){
	let timer = null
  return function(...rest){
  	if(timer)return
    timer = setTimeout(()=>{
      fun.apply(this, rest)
      clearTimeout(timer)
      timer = null
    }, time)
  }
}

const callback = function(...rest){
	console.log((new Date().getTime()), rest)
}

window.addEventListener('scroll', throttle(callback, 1000))

过程: 两者均是利用外层函数提供一个变量共内层函数使用; 时间戳版本,通过时间来比较,如果间隔时间内执行过了才重新计时; 定时器版本,通过定时器,如果定时器执行过了才会重新设置定时器; ​

防抖和节流的主要区别:防抖是一段时间内触发了,就清除定时器重新计时,直到一段时间内没有触发了,才执行回调;而节流是一段时间内触发多次了,只会执行一次回调,并重新计时。