前面给大家发了一篇文章xxx,给大家介绍了一遍JavaScript中的装饰器,今天就给大家介绍一下在我项目中用到过的几个装饰器的思路吧!
代码是伪代码,只是提供个思路,实际上代码不止这么少。
当我们在一些特殊场景时,需要使用防抖这个优化手段来进行优化,比如:
这些函数都可以使用防抖装饰器来进行性能优化,防抖的意思是,当你频繁执行某一个操作时,这个操作只执行最后一次,确保不会因为频繁的执行而损耗性能~下面是装饰器的封装:
// 装饰器的封装function debounce(delay) { return function(target, key, descriptor) { const originalMethod = descriptor.value; let timer; descriptor.value = function(...args) { clearTimeout(timer); timer = setTimeout(() => { originalMethod.apply(this, args); }, delay); }; return descriptor; };}
当我们某个函数需要进行防抖处理时:
@debounce(500)submit() {}@debounce(500)handleChange() {}@debounce(500)handleFilter() {}
节流跟防抖是不同的优化手段,节流是保证在一段时间内只执行一次操作,适用在这些场景中:
下面是装饰器的封装:
function throttle(delay) { return function(target, key, descriptor) { const originalMethod = descriptor.value; let timer; let lastExecTime = 0; descriptor.value = function(...args) { const now = Date.now(); if (now - lastExecTime >= delay) { lastExecTime = now; originalMethod.apply(this, args); } else { clearTimeout(timer); timer = setTimeout(() => { originalMethod.apply(this, args); }, delay); } }; return descriptor; };}
当我们某个函数需要进行节流处理时:
@throttle(200)handleScroll() {}@throttle(200)handleResize() {}
日志的输出是很重要的,尤其是在 Nodejs 端,日志输出会通过 pm2 等工具,记录在一些日志文件里,尤其是一些比较公用的工具函数,更是非常重要,一般需要记录这些内容。
下面是装饰器的封装:
function log(target, key, descriptor) { const originalMethod = descriptor.value; descriptor.value = function(...args) { console.log(`Entering ${key} with arguments:`, args); const result = originalMethod.apply(this, args); console.log(`Exiting ${key} with result:`, result); return result; }; return descriptor;}
使用的时候:
class Common { @log() commonRequest(url, params) { return request(url, params) }}const common = new Common()common.commonRequest('http://xxx.com', { name: 'l' })Entering commonRequest with arguments: ['http://xxx.com', { name: 'l' }]Exiting commonRequest with result: { 结果 }
跟日志装饰器一样,错误其实也是日志的一部分,错误日志非常重要,因为 Nodejs 的线上报错,大部分都需要通过查日志来进行定位,所以我们也可以封装一个错误的处理装饰器:
function errorHandler(target, key, descriptor) { const originalMethod = descriptor.value; descriptor.value = function (...args) { try { originalMethod.apply(this, args); } catch (error) { console.error(`Error occurred in ${key}:`, error); } }; return descriptor;}
使用的时候:
class Common { @log() commonRequest(url, params) { return request(url, params) }}const common = new Common()common.commonRequest('http://xxx.com', { name: 'l' })Error occurred in commonRequest: Request Error
权限的校验在前端一般都不用装饰器,但是在 Nodejs 管理接口时,涉及到权限校验时,用装饰器是非常的方便的。
function authenticated(target, key, descriptor) { const originalMethod = descriptor.value; descriptor.value = function(...args) { if (isAuthenticated()) { originalMethod.apply(this, args); } else { console.log('Unauthorized access!'); } }; return descriptor;}
使用的时候,这样就只有 admin 的身份可以访问这个接口了。
class User { @Get('/xx/xx') @authenticated('admin') getUser() {}}
如果有一天,你们需要埋点,计算一些比较重要函数的运行性能时,那么你肯定需要计算这些函数的执行时间是多少,这时候封装一个计时装饰器会让你非常方便。
function timing(target, key, descriptor) { const originalMethod = descriptor.value; descriptor.value = function(...args) { const start = performance.now(); const result = originalMethod.apply(this, args); const end = performance.now(); console.log(`Execution time of ${key}: ${end - start} milliseconds`); return result; }; return descriptor;}
使用时:
class Common { @timing() commonRequest(url, params) { return request(url, params) }}const common = new Common()common.commonRequest()Execution time of commonRequest: 20 milliseconds
这个装饰器适用在某一些场景,如果你有一个函数是用来计算值的,并且计算的过程非常复杂非常耗时间,那我建议你可以把这些计算结果储存起来,而不是每次都重新计算,这能大大提升你的计算性能。
function cache(target, key, descriptor) { const originalMethod = descriptor.value; const cache = new Map(); descriptor.value = function(...args) { const cacheKey = JSON.stringify(args); if (cache.has(cacheKey)) { return cache.get(cacheKey); } const result = originalMethod.apply(this, args); cache.set(cacheKey, result); return result; }; return descriptor;}
使用时:
class Compute() { @cache() run(num1, num2) { // 这里举个简单例子 return num1 + num2 }}const c = new Compute()c.run(1, 2) // 3 首次计算c.run(1, 2) // 3 接下来都从缓存中拿
在老项目中,无法用到 typescript 这么好的东西时,对于一些函数执行时,有必要用装饰器对传进来的参数的类型进行校验~没办法,没有 typescript 真难受啊!
function validateArgs(...types) { return function (target, key, descriptor) { const originalMethod = descriptor.value; descriptor.value = function (...args) { for (let i = 0; i < types.length; i++) { const type = types[i]; const arg = args[i]; if (typeof arg !== type) { throw new Error(`Invalid argument type at index ${i}`); } } originalMethod.apply(this, args); }; return descriptor; };}
使用的时候需要传入某个参数的类型限制。
class Common { @validateArgs(['string', 'object']) commonRequest(url, params) { return request(url, params) }}const common = new Common()common.commonRequest(123, 123) // 报错
本文链接:http://www.28at.com/showinfo-26-89713-0.html分享能提高开发效率,提高代码质量的八个前端装饰器函数
声明:本网页内容旨在传播知识,不代表本站观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。