自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

分享能提高開發(fā)效率,提高代碼質(zhì)量的八個(gè)前端裝飾器函數(shù)

開發(fā) 前端
日志的輸出是很重要的,尤其是在 Nodejs 端,日志輸出會(huì)通過 pm2 等工具,記錄在一些日志文件里,尤其是一些比較公用的工具函數(shù),更是非常重要,一般需要記錄這些內(nèi)容。

裝飾器非常好用

前面給大家發(fā)了一篇文章xxx,給大家介紹了一遍JavaScript中的裝飾器,今天就給大家介紹一下在我項(xiàng)目中用到過的幾個(gè)裝飾器的思路吧!

代碼是偽代碼,只是提供個(gè)思路,實(shí)際上代碼不止這么少。

防抖裝飾器

當(dāng)我們?cè)谝恍┨厥鈭?chǎng)景時(shí),需要使用防抖這個(gè)優(yōu)化手段來進(jìn)行優(yōu)化,比如:

  • 表單提交
  • 數(shù)據(jù)的搜索
  • 數(shù)據(jù)的篩選
  • 某些數(shù)據(jù)的更改
  • 數(shù)據(jù)改變時(shí)觸發(fā)的回調(diào)

這些函數(shù)都可以使用防抖裝飾器來進(jìn)行性能優(yōu)化,防抖的意思是,當(dāng)你頻繁執(zhí)行某一個(gè)操作時(shí),這個(gè)操作只執(zhí)行最后一次,確保不會(huì)因?yàn)轭l繁的執(zhí)行而損耗性能~下面是裝飾器的封裝:

// 裝飾器的封裝
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;
  };
}

當(dāng)我們某個(gè)函數(shù)需要進(jìn)行防抖處理時(shí):

@debounce(500)
submit() {}

@debounce(500)
handleChange() {}

@debounce(500)
handleFilter() {}

節(jié)流裝飾器

節(jié)流跟防抖是不同的優(yōu)化手段,節(jié)流是保證在一段時(shí)間內(nèi)只執(zhí)行一次操作,適用在這些場(chǎng)景中:

  • 監(jiān)聽窗口寬度變化的回調(diào)
  • 監(jiān)聽滾動(dòng)條變化的回調(diào)

下面是裝飾器的封裝:

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;
  };
}

當(dāng)我們某個(gè)函數(shù)需要進(jìn)行節(jié)流處理時(shí):

@throttle(200)
handleScroll() {}

@throttle(200)
handleResize() {}

日志輸出裝飾器

日志的輸出是很重要的,尤其是在 Nodejs 端,日志輸出會(huì)通過 pm2 等工具,記錄在一些日志文件里,尤其是一些比較公用的工具函數(shù),更是非常重要,一般需要記錄這些內(nèi)容。

  • 執(zhí)行的函數(shù)名稱
  • 執(zhí)行時(shí)傳入的參數(shù)
  • 執(zhí)行后獲取到的結(jié)果

下面是裝飾器的封裝:

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;
}

使用的時(shí)候:

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: { 結(jié)果 }

錯(cuò)誤處理裝飾器

跟日志裝飾器一樣,錯(cuò)誤其實(shí)也是日志的一部分,錯(cuò)誤日志非常重要,因?yàn)?Nodejs 的線上報(bào)錯(cuò),大部分都需要通過查日志來進(jìn)行定位,所以我們也可以封裝一個(gè)錯(cuò)誤的處理裝飾器:

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;
}

使用的時(shí)候:

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

權(quán)限校驗(yàn)裝飾器

權(quán)限的校驗(yàn)在前端一般都不用裝飾器,但是在 Nodejs 管理接口時(shí),涉及到權(quán)限校驗(yàn)時(shí),用裝飾器是非常的方便的。

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;
}

使用的時(shí)候,這樣就只有 admin 的身份可以訪問這個(gè)接口了。

class User {  
    @Get('/xx/xx')
    @authenticated('admin')
    getUser() {}
}

計(jì)時(shí)裝飾器

如果有一天,你們需要埋點(diǎn),計(jì)算一些比較重要函數(shù)的運(yùn)行性能時(shí),那么你肯定需要計(jì)算這些函數(shù)的執(zhí)行時(shí)間是多少,這時(shí)候封裝一個(gè)計(jì)時(shí)裝飾器會(huì)讓你非常方便。

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;
}

使用時(shí):

class Common {
    @timing()
    commonRequest(url, params) {
        return request(url, params)
    }
}

const common = new Common()
common.commonRequest()
Execution time of commonRequest: 20 milliseconds

緩存裝飾器

這個(gè)裝飾器適用在某一些場(chǎng)景,如果你有一個(gè)函數(shù)是用來計(jì)算值的,并且計(jì)算的過程非常復(fù)雜非常耗時(shí)間,那我建議你可以把這些計(jì)算結(jié)果儲(chǔ)存起來,而不是每次都重新計(jì)算,這能大大提升你的計(jì)算性能。

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;
}

使用時(shí):

class Compute() {
    @cache()
    run(num1, num2) {
        // 這里舉個(gè)簡(jiǎn)單例子
        return num1 + num2
    }
}

const c = new Compute()
c.run(1, 2) // 3 首次計(jì)算
c.run(1, 2) // 3 接下來都從緩存中拿

參數(shù)校驗(yàn)裝飾器

在老項(xiàng)目中,無法用到 typescript 這么好的東西時(shí),對(duì)于一些函數(shù)執(zhí)行時(shí),有必要用裝飾器對(duì)傳進(jìn)來的參數(shù)的類型進(jìn)行校驗(yàn)~沒辦法,沒有 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;
  };
}

使用的時(shí)候需要傳入某個(gè)參數(shù)的類型限制。

class Common {
    @validateArgs(['string', 'object'])
    commonRequest(url, params) {
        return request(url, params)
    }
}

const common = new Common()
common.commonRequest(123, 123) // 報(bào)錯(cuò)


責(zé)任編輯:武曉燕 來源: 前端之神
相關(guān)推薦

2022-08-26 14:41:47

Python數(shù)據(jù)科學(xué)開源

2020-03-18 15:54:41

開發(fā)效率代碼

2021-01-08 10:38:40

前端開發(fā)代碼

2021-08-02 09:29:08

Vscode開發(fā)Web

2022-08-16 10:32:08

Python數(shù)據(jù)科學(xué)

2016-02-23 11:03:03

代碼質(zhì)量編寫函數(shù)

2024-09-23 09:00:00

裝飾器函數(shù)代碼

2015-08-11 09:39:25

重構(gòu)提高代碼質(zhì)量

2016-02-24 16:03:34

代碼質(zhì)量編寫函數(shù)

2018-09-27 09:00:00

DjangoPython

2024-03-08 08:00:00

Python開發(fā)裝飾器

2015-07-15 10:27:48

Android代碼質(zhì)量工具

2023-09-01 07:31:41

工具工具類網(wǎng)站

2024-09-12 15:32:35

裝飾器Python

2023-01-06 18:31:46

準(zhǔn)確命名

2015-12-15 09:50:12

Linux開發(fā)效率工具

2023-11-22 08:26:03

HutoolJava工具集

2022-09-05 14:17:48

Javascript技巧

2022-08-04 09:01:45

TypeScriptMicrosoft

2012-10-24 14:17:25

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)