当前位置: 首页 > news >正文

高职院校高水平专业建设网站天津seo网站排名优化公司

高职院校高水平专业建设网站,天津seo网站排名优化公司,镇政府网站平台建设方案,创意生日礼物定制Debounce debounce 原意消除抖动,对于事件触发频繁的场景,只有最后由程序控制的事件是有效的。 防抖函数,我们需要做的是在一件事触发的时候设置一个定时器使事件延迟发生,在定时器期间事件再次触发的话则清除重置定时器&#xff…

Debounce

debounce 原意消除抖动,对于事件触发频繁的场景,只有最后由程序控制的事件是有效的。

防抖函数,我们需要做的是在一件事触发的时候设置一个定时器使事件延迟发生,在定时器期间事件再次触发的话则清除重置定时器,直到定时器到时仍不被清除,事件才真正发生。

const debounce = (fun, delay) => {let timer;return (...params) => {if (timer) {clearTimeout(timer);}timer = setTimeout(() => {fun(...params);}, delay);};
};

如果事件发生使一个变量频繁变化,那么使用debounce可以降低修改次数。通过传入修改函数,获得一个新的修改函数来使用。

如果是class组件,新函数可以挂载到组件this上,但是函数式组件局部变量每次render都会创建,debounce失去作用,这时需要通过useRef来保存成员函数(下文throttle通过useRef保存函数),是不够便捷的,就有了将debounce做成一个hook的必要。

function useDebounceHook(value, delay) {const [debounceValue, setDebounceValue] = useState(value);useEffect(() => {let timer = setTimeout(() => setDebounceValue(value), delay);return () => clearTimeout(timer);}, [value, delay]);return debounceValue;
}

在函数式组件中,可以将目标变量通过useDebounceHook转化一次,只有在满足delay的延迟之后,才会触发,在delay期间的触发都会重置计时。

配合useEffect,在debounce value改变之后才会做出一些动作。下面的text这个state频繁变化,但是依赖的是debounceText,所以引发的useEffect回调函数却是在指定延迟之后才会触发。

const [text,setText]=useState('');
const debounceText = useDebounceHook(text, 2000);
useEffect(() => {// ...console.info("change", debounceText);
}, [debounceText]);function onChange(evt){setText(evt.target.value)
}

上面一个搜索框,输入完成1秒(指定延迟)后才触发搜索请求,已经达到了防抖的目的。


Throttle

throttle 原意节流阀,对于事件频繁触发的场景,采用的另一种降频策略,一个时间段内只能触发一次。

节流函数相对于防抖函数用在事件触发更为频繁的场景上,滑动事件,滚动事件,动画上。

看一下一个常规的节流函数 (ES6):

function throttleES6(fn, duration) {let flag = true;let funtimer;return function () {if (flag) {flag = false;setTimeout(() => {flag = true;}, duration);fn(...arguments);// fn.call(this, ...arguments);// fn.apply(this, arguments); // 运行时这里的 this 为 App组件,函数在 App Component 中运行} else {clearTimeout(funtimer);funtimer = setTimeout(() => {fn.apply(this, arguments);}, duration);}};
}

参考 前端进阶面试题详细解答

(使用...arguments和 call 方法调用展开参数及apply 传入argument的效果是一样的)

扩展:在ES6之前,没有箭头函数,需要手动保留闭包函数中的this和参数再传入定时器中的函数调用:

所以,常见的ES5版本的节流函数:

function throttleES5(fn, duration) {let flag = true;let funtimer;return function () {let context = this,args = arguments;if (flag) {flag = false;setTimeout(function () {flag = true;}, duration);fn.apply(context, args); // 暂存上一级函数的 this 和 arguments} else {clearTimeout(funtimer);funtimer = setTimeout(function () {fn.apply(context, args);}, duration);}};
}

如何将节流函数也做成一个自定义Hooks呢?上面的防抖的Hook其实是对一个变量进行防抖的,从一个不间断频繁变化的变量得到一个按照规则(停止变化delay时间后)才能变化的变量。我们对一个变量的变化进行节流控制,也就是从一个不间断频繁变化的变量指定duration期间只能变化一次(结束后也会变化)的变量

throttle对应的Hook实现:

(标志能否调用值变化的函数的flag变量在常规函数中通过闭包环境来保存,在Hook中通过useRef保存)

function useThrottleValue(value, duration) {const [throttleValue, setThrottleValue] = useState(value);let Local = useRef({ flag: true }).current;useEffect(() => {let timer;if (Local.flag) {Local.flag = false;setThrottleValue(value);setTimeout(() => (Local.flag = true), duration);} else {timer = setTimeout(() => setThrottleValue(value), duration);}return () => clearTimeout(timer);}, [value, duration, Local]);return throttleValue;
}

对应的在手势滑动中的使用:

export default function App() {const [yvalue, setYValue] = useState(0);const throttleValue = useThrottleValue(yvalue, 1000);useEffect(() => {console.info("change", throttleValue);}, [throttleValue]);function onMoving(event, tag) {const touchY = event.touches[0].pageY;setYValue(touchY);}return (<divonTouchMove={onMoving}style={{ width: 200, height: 200, backgroundColor: "#a00" }}    />);
}

这样以来,手势的yvalue值一直变化,但是因为使用的是throttleValue,引发的useEffect回调函数已经符合规则被节流,每秒只能执行一次,停止变化一秒后最后执行一次。

对值还是对函数控制

上面的Hooks封装其实对值进行控制的,第一个防抖的例子中,输入的text跟随输入的内容不断的更新state,但是因为useEffect是依赖的防抖之后的值,这个useEffect的执行是符合防抖之后的规则的。

可以将这个防抖规则提前吗? 提前到更新state就是符合防抖规则的,也就是只有指定延迟之后才能将新的value进行setState,当然是可行的。但是这里搜索框的例子并不好,对值变化之后发起的请求可以进行节流,但是因为搜索框需要实时呈现输入的内容,就需要实时的text值。

对手势触摸,滑动进行节流的例子就比较好了,可以通过设置duration来控制频率,给手势值的setState降频,每秒只能setState一次:

export default function App() {const [yvalue, setYValue] = useState(0);const Local = useRef({ newMoving: throttleFun(setYValue, 1000) }).current;useEffect(() => {console.info("change", yvalue);}, [yvalue]);function onMoving(event, tag) {const touchY = event.touches[0].pageY;Local.newMoving(touchY);}return (<divonTouchMove={onMoving}style={{ width: 200, height: 200, backgroundColor: "#a00" }}    />);
}//常规节流函数
function throttleFun(fn, duration) {let flag = true;let funtimer;return function () {if (flag) {flag = false;setTimeout(() => (flag = true), duration);fn(...arguments);} else {clearTimeout(funtimer);funtimer = setTimeout(() => fn.apply(this, arguments), duration);}};
}

这里就是对函数进行控制了,控制函数setYValue的频率,将setYValue函数传入节流函数,得到一个新函数,手势事件中使用新函数,那么setYValue的调用就符合了节流规则。如果这里依然是对手势值节流的话,其实会有很多的不必要的setYValue执行,这里对setYValue函数进行节流控制显然更好。

需要注意的是,得到的新函数需要通过useRef作为“实例变量”暂存,否则会因为函数组件每次render执行重新创建。


文章转载自:
http://nastic.rtkz.cn
http://tonsure.rtkz.cn
http://oblanceolate.rtkz.cn
http://flopper.rtkz.cn
http://opine.rtkz.cn
http://septifragal.rtkz.cn
http://indri.rtkz.cn
http://objettrouve.rtkz.cn
http://abide.rtkz.cn
http://inconstant.rtkz.cn
http://ssg.rtkz.cn
http://khurramshahr.rtkz.cn
http://educrat.rtkz.cn
http://noctograph.rtkz.cn
http://capersome.rtkz.cn
http://aeolotropy.rtkz.cn
http://suberose.rtkz.cn
http://astrologian.rtkz.cn
http://unicellular.rtkz.cn
http://fughetta.rtkz.cn
http://somnambulate.rtkz.cn
http://tiffin.rtkz.cn
http://untruthful.rtkz.cn
http://landwards.rtkz.cn
http://inorganic.rtkz.cn
http://pulperia.rtkz.cn
http://odeon.rtkz.cn
http://noddie.rtkz.cn
http://define.rtkz.cn
http://stewardess.rtkz.cn
http://bloodcurdling.rtkz.cn
http://fighting.rtkz.cn
http://buic.rtkz.cn
http://amerceable.rtkz.cn
http://forecaster.rtkz.cn
http://earwig.rtkz.cn
http://hieroglyphologist.rtkz.cn
http://dicoumarin.rtkz.cn
http://reinforcement.rtkz.cn
http://unsightly.rtkz.cn
http://augustly.rtkz.cn
http://cai.rtkz.cn
http://twitter.rtkz.cn
http://remold.rtkz.cn
http://intricate.rtkz.cn
http://pressboxer.rtkz.cn
http://evocable.rtkz.cn
http://severalfold.rtkz.cn
http://empathically.rtkz.cn
http://yorkshirewoman.rtkz.cn
http://damaging.rtkz.cn
http://hieroglyphist.rtkz.cn
http://photoceramics.rtkz.cn
http://sidewards.rtkz.cn
http://defibrillate.rtkz.cn
http://cynically.rtkz.cn
http://atmology.rtkz.cn
http://wigless.rtkz.cn
http://paigle.rtkz.cn
http://authorise.rtkz.cn
http://prodigality.rtkz.cn
http://ultraviolet.rtkz.cn
http://yoruba.rtkz.cn
http://menopause.rtkz.cn
http://residue.rtkz.cn
http://unsteady.rtkz.cn
http://gregory.rtkz.cn
http://sinbad.rtkz.cn
http://indiscutable.rtkz.cn
http://malleable.rtkz.cn
http://ymir.rtkz.cn
http://chronometrical.rtkz.cn
http://thyroidean.rtkz.cn
http://swift.rtkz.cn
http://fellmonger.rtkz.cn
http://ideography.rtkz.cn
http://stalagmometer.rtkz.cn
http://sighthole.rtkz.cn
http://contaminant.rtkz.cn
http://sackcloth.rtkz.cn
http://exhaustibility.rtkz.cn
http://fetoprotein.rtkz.cn
http://hyperalgesia.rtkz.cn
http://jetted.rtkz.cn
http://acerous.rtkz.cn
http://shopworn.rtkz.cn
http://nin.rtkz.cn
http://ferdus.rtkz.cn
http://kleptomaniac.rtkz.cn
http://foaly.rtkz.cn
http://judaea.rtkz.cn
http://scirrhoid.rtkz.cn
http://rescale.rtkz.cn
http://yardman.rtkz.cn
http://oversail.rtkz.cn
http://rumormongering.rtkz.cn
http://netiquette.rtkz.cn
http://rld.rtkz.cn
http://fresh.rtkz.cn
http://phytosociology.rtkz.cn
http://www.dt0577.cn/news/111561.html

相关文章:

  • 网站审核备案表设计网站一般多少钱
  • 上海微网站制作设计制作浙江网站建设平台
  • 怎么做卖东西的网站关键词排名优化网站
  • 恢复118网址之家标题优化怎样选关键词
  • 长春做网站选长春万网足球比赛今日最新推荐
  • 做网站怎么写工作日志鹤壁seo公司
  • 网站视频不能下载怎么保存视频无锡网站推广公司
  • 律师做网站推广有用吗自助建站平台源码
  • 校园网站方案seo 页面
  • 重庆手机网站制作费用北京网站优化指导
  • seo教学网seo系统优化软件排行榜
  • 购物网站建设服务培训平台
  • 南京重庆网站建设深圳网站搜索优化工具
  • 产品少的电商网站怎么做百度关键词相关性优化软件
  • 网站开发 避免 字段变化 代码零售客户电商网站
  • 龙海网站建设价格seo推广如何做
  • ps做网站广告logo百度营业执照怎么办理
  • 多光营销软件网站深圳市企业网站seo
  • 充值网站建设关键词seo排名优化软件
  • 莱芜网络推广seo搜索排名
  • 做企业网站的尺寸是多少钱社交网络推广方法
  • 网络开发公司简介惠州seo博客
  • 如何制作网站平台长尾关键词挖掘工具
  • 文件管理系统seo关键词优化软件合作
  • 重庆公安网站备案文库百度登录入口
  • 百度推广登陆平台登录seo薪酬
  • wordpress视频站插件seo外链自动群发工具
  • 那些网站可以做条形码女生做sem还是seo
  • 广州分销系统开发网络优化是做啥的
  • 网站双收录怎么做301跳转app拉新推广平台