再谈函数节流与防抖 - 利用装饰器 @decorator 来实现

距离 第一次听到 节流与防抖 已经过去两年的时间,最近也是新看到一道题重新复习下老的知识点,并且提出新的解决方案。 # 先温习一下之前已经知道的经典方法: // 节流 高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率 exports.throttle = function (fn, limit = 1000) { let flag = true; return function () { if (!flag) { return; } flag = false; setTimeout(() => { fn.apply(this, arguments); flag = true; }, limit); }; } // 防抖 触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间 exports.debounce = function (fn, limit = 1000) { let flag = null; return function () { clearTimeout(flag); flag = setTimeout(() => { fn.apply(this, arguments); }, limit); }; } # 下面抛出新抛出的问题,如何用 @decorator装饰器 来实现呢? 装饰者模式就是动态的给类或对象增加功能的设计模式。虽然在浏览器中还没有被实现,但在TypeScript里已做为一项实验性特性予以支持。 安装TS、调试步骤之类的过程略去,可以参考handbook;下面小记一下decorator的重点:Decorators的实现使用了ES5的 Object.defineProperty 方法,这三个参数也和这个方法的参数一致。装饰器的本质就是一个函数语法糖,通过Object.defineProperty来修改类中一些属性,descriptor参数也是一个对象,是针对key属性的描述符,里面有控制目标对象的该属性是否可写的writable属性等。 function throttle(limit: number = 0) { let flag = true return (target: any, key: string, descriptor: any) => { let func = descriptor.value descriptor.value = async (...args: any[]) => { if(!flag) return flag = false try { func.apply(this, ...args) } catch (error) { console.log(error) } if (!limit) return flag = true setTimeout(() => { flag = true }, limit); } } } class TestD{ @throttle(2000) fn() { console.log('fn') } } const testd = new TestD() setInterval(testd.fn,50); 以上便完成了节流装饰器的操作,说好了问节流和防抖,转头就考了装饰器,老阴阳人了。 参考文档: js防抖节流新姿势 typescript-handbook - Decorator TS下的装饰者模式(Decorator)

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):