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

网站制作怎样快速/百度超级链数字藏品

网站制作怎样快速,百度超级链数字藏品,做药品的电商网站,网站开发用什么语言开发的之前遇到过一个场景,页面上有几个d3.js绘制的图形。如果调整浏览器可视区大小,会引发图形重绘。当图中的节点比较多的时候,页面会显得异常卡顿。为了限制类似于这种短时间内高频率触发的情况,我们可以使用防抖函数。 实际开发过程…

  之前遇到过一个场景,页面上有几个d3.js绘制的图形。如果调整浏览器可视区大小,会引发图形重绘。当图中的节点比较多的时候,页面会显得异常卡顿。为了限制类似于这种短时间内高频率触发的情况,我们可以使用防抖函数。

  实际开发过程中,这样的情况其实很多,比如:

  • 页面的scroll事件
  • input框等的输入事件
  • 拖拽事件用到的mousemove等

  先说说防抖和节流是个啥,有啥区别

防抖:设定一个时间间隔,当某个频繁触发的函数执行一次后,在这个时间间隔内不会再次被触发,如果在此期间尝试触发这个函数,则时间间隔会重新开始计算。

节流:设定一个时间间隔,某个频繁触发的函数,在这个时间间隔内只会执行一次。也就是说,这个频繁触发的函数会以一个固定的周期执行。

debounce(函数防抖)

  大致捋一遍代码结构。为了方便阅读,我们先把源码中的Function注释掉。

function debounce(func, wait, options) {// 代码一开始,以闭包的形式定义了一些变量var lastArgs,  //  最后一次debounce的arguments,它其实起一个标记位的作用,后面会提到lastThis,  //  就是last this,用来修正this指向maxWait,   //  存储option里面传入的maxWait值,最大等待时间result,    //  其实这个result始终都是undefinedtimerId,   // setTimeout赋给它,用于表示当前定时器lastCallTime,   // 最后一次调用debounce的时刻lastInvokeTime = 0,    //  最后一次调用用户传入函数的时刻leading = false,   //  是否在一开始就执行用户传入的函数maxing = false,    //  是否有最大等待时间trailing = true;   //  是否在等待周期结束后执行用户传入的函数//  用户传入的fun必须是个函数,否则报错if (typeof func != 'function') {throw new TypeError(FUNC_ERROR_TEXT);}//  toNumber是lodash封装的一个转类型的方法wait = toNumber(wait) || 0;//  获取用户传入的配置if (isObject(options)) {leading = !!options.leading;maxing = 'maxWait' in options;maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;trailing = 'trailing' in options ? !!options.trailing : trailing;}//  执行用户传入的函数function invokeFunc(time) {// ......}//  防抖开始时执行的操作function leadingEdge(time) {)// ......}//  计算仍然需要等待的时间function remainingWait(time) {// ......}//  判断此时是否应该执行用户传入的函数function shouldInvoke(time) {// ......}//  等待时间结束后的操作function timerExpired() {// ......}//  执行用户传入的函数function trailingEdge(time) {// ......}//  取消防抖function cancel() {// ......}//  立即执行用户传入的函数function flush() {// ......}// 防抖开始的入口function debounced() {// ......}debounced.cancel = cancel;debounced.flush = flush;return debounced;}

我们先从入口函数开始。函数开始执行后,首先会出现三种情况:

  • 时间上达到了可以执行的条件;
  • 时间上不满足条件,但是此时的定时器并没有启动;
  • 不满足条件,返回undefined

  说实话,第二种情况没想到场景,哪位大佬给补充一下呢。

  代码中timerId = setTimeout(timerExpired, wait);是用来设置定时器,到时间后触发trailingEdge这个函数。

function debounced() {var time = now(),isInvoking = shouldInvoke(time);   // 判断此时是否可以开始执行用户传入的函数lastArgs = arguments;lastThis = this;lastCallTime = time;if (isInvoking) {// 如果此时并没有定时器存在,就开始进入防抖阶段if (timerId === undefined) {return leadingEdge(lastCallTime);}//  如果设置了最大等待时间,便立即执行用户传入的函数if (maxing) {// Handle invocations in a tight loop.timerId = setTimeout(timerExpired, wait);return invokeFunc(lastCallTime);}}if (timerId === undefined) {timerId = setTimeout(timerExpired, wait);}//  不满足条件,return undefinedreturn result;}

  我们先来看看shouldInvoke是如何判断函数是否可以执行的。

      function shouldInvoke(time) {//  lastCallTime初始值是undefined,lastInvokeTime初始值是0,//  防抖函数被手动取消后,这两个值会被设为初始值var timeSinceLastCall = time - lastCallTime,timeSinceLastInvoke = time - lastInvokeTime;// Either this is the first call, activity has stopped and we're at the// trailing edge, the system time has gone backwards and we're treating// it as the trailing edge, or we've hit the `maxWait` limit.return (lastCallTime === undefined ||   //  初次执行(timeSinceLastCall >= wait) ||  //  上次调用时刻距离现在已经大于wait值(timeSinceLastCall < 0) ||      //  当前时间-上次调用时间小于0,应该只可能是手动修改了系统时间吧(maxing && timeSinceLastInvoke >= maxWait)  //  设置了最大等待时间,且已超时);}

  我们继续分析函数开始的阶段leadingEdge。首先重置防抖函数最后调用时间,然后去触发一个定时器,保证wait后接下来的执行。最后判断如果leadingtrue的话,立即执行用户传入的函数:

      function leadingEdge(time) {// Reset any `maxWait` timer.lastInvokeTime = time;// Start the timer for the trailing edge.timerId = setTimeout(timerExpired, wait);// Invoke the leading edge.return leading ? invokeFunc(time) : result;}

  我们已经不止一次去设定触发器了,来我们探究一下里面到底做了啥。其实很简单,判断时间是否符合执行条件,符合的话触发trailingEdge,也就是后续操作,否则计算需要等待的时间,并重新调用这个函数,其实这里就是防抖的核心所在了。

      function timerExpired() {var time = now();if (shouldInvoke(time)) {return trailingEdge(time);}// Restart the timer.timerId = setTimeout(timerExpired, remainingWait(time));}

  至于如何重新计算剩余时间的,这里不作过多解释,大家一看便知。

      function remainingWait(time) {var timeSinceLastCall = time - lastCallTime,timeSinceLastInvoke = time - lastInvokeTime,timeWaiting = wait - timeSinceLastCall;return maxing? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke): timeWaiting;}

  我们说说等待时间到了以后的操作。重置了一些本周期的变量。并且,如果trailingtrue而且lastArgs存在时,才会再次执行用户传入的参数。这里解释了文章开头提到的lastArgs只是个标记位,如注释所说,他表示debounce至少执行了一次。

      function trailingEdge(time) {timerId = undefined;// Only invoke if we have `lastArgs` which means `func` has been// debounced at least once.if (trailing && lastArgs) {return invokeFunc(time);}lastArgs = lastThis = undefined;return result;}

  执行用户传入的函数比较简单,我们知道callapply是会立即执行的,其实最后的result还是undefined

    function invokeFunc(time) {var args = lastArgs,thisArg = lastThis;//  重置了一些条件lastArgs = lastThis = undefined;lastInvokeTime = time;//  执行用户传入函数result = func.apply(thisArg, args);return result;}

  最后就是取消防抖和立即执行用户传入函数的过程了,代码一目了然,不作过多解释。

      function cancel() {if (timerId !== undefined) {clearTimeout(timerId);}lastInvokeTime = 0;lastArgs = lastCallTime = lastThis = timerId = undefined;}function flush() {return timerId === undefined ? result : trailingEdge(now());}

throttle(函数节流)

  节流其实原理跟防抖是一样的,只不过触发条件不同而已,其实就是maxWaitwait的防抖函数。

    function throttle(func, wait, options) {var leading = true,trailing = true;if (typeof func != 'function') {throw new TypeError(FUNC_ERROR_TEXT);}if (isObject(options)) {leading = 'leading' in options ? !!options.leading : leading;trailing = 'trailing' in options ? !!options.trailing : trailing;}return debounce(func, wait, {'leading': leading,'maxWait': wait,'trailing': trailing});}

总结

  我们发现,其实lodash除了在cancle函数中使用了清除定时器的操作外,其他地方并没有去关心定时器,而是很巧妙的在定时器里加了一个判断条件来判断后续函数是否可以执行。这就避免了手动管理定时器。

  lodash替我们考虑到了一些比较少见的情景,而且还有一定的容错性。即便ES6实现了很多目前常用的工具函数,但是面对复杂的情景,我们依然可以以按需引入的方式使用lodash的一些函数来提升开发效率,同时使得我们的程序更加健壮。

http://www.lbrq.cn/news/1561177.html

相关文章:

  • 群晖wordpress目录/白云百度seo公司
  • 量个网站一个域名/怎么开网店
  • 网站建设微信商城运营/如何做好网络销售技巧
  • 购物展示网站开发的背景/新手如何涨1000粉
  • 阿里巴巴做国际网站要多少钱/seo包括哪些方面
  • 电子商务网站的建设流程/建站推广网站
  • 怎样做微商网站/seo网络排名优化哪家好
  • 网站开发的pc或移动端/网络销售新手入门
  • 问卷调查网站赚钱/腾讯新闻发布平台
  • 国家企业信用信息查询系统官网/seo主要做什么工作
  • 外贸soho网站建设/站长之家怎么找网址
  • 公司网站建设深圳/一起来看在线观看免费
  • 百度做网站要多长时间/学市场营销后悔死了
  • 承德项目网/seo就业指导
  • 妈妈在家里做女视频网站/天津seo推广
  • 湛江网站开发/网络工程师是干什么的
  • 池州网站建设公司/类似58的推广平台有哪些平台
  • 百度抓取网站/百度 seo 工具
  • 石家庄网站建设公司哪个好/百度视频推广怎么收费
  • wordpress 文章标签 调用/东莞网站关键词优化排名
  • 网站开发的app/长沙 建站优化
  • 外贸soho建网站/上海知名网站制作公司
  • 代加工厂接单平台/优化大师apk
  • 做英文网站公司/长沙网站排名推广
  • 电商设计网站素材/亚马逊排名seo
  • wordpress 显示空白页/广州seo外包多少钱
  • 网站优化的监测评估/seo排名优化软件免费
  • 中山做网站费用/深圳网站优化培训
  • 销售网站开发步骤/怎么样免费做网站
  • 建设银行泰安培训中心官方网站/广州官方新闻
  • 【Spring Cloud 微服务】1.Hystrix断路器
  • 初识CNN02——认识CNN2
  • 机器学习之PCA降维
  • springboot博客实战笔记02
  • 4. 索引数据的增删改查
  • 亚马逊品牌权力重构:第三方卖家崛起下的竞争生态与系统性应对框架