感覺面向切面編程

什麼是面向切面

初聽面向切面編程時, 一頭霧水, 什麼是面向切面, 只據說過面向對象(OOP), 面向過程(PO), 函數式編程(FP), 面向切面 ? 面向的難道是某一個面?前端

面向搜索引擎後才瞭解到, 面向切面是一種編程範式(Aspect Oriented Programming), 簡寫 AOP, 特色是與原有邏輯解耦, 無侵入.ios

在後端開發工做中, 常見使用的場景是 斷點調試/打印日誌/...,編程

而在前端開發工做中, 應用場景比較靈活多變, 能夠是在一次表單提交中, 在表單提交前做表單驗證(前置), 或在表單提交後做數據刷新/頁面跳轉/Cookie 刷新等 (後置), 也能夠在提交的同時做數據埋點(橫向), 或是打印日誌。。。
對於外部的新加入的邏輯, 爲了避免破壞原有的業務邏輯, 咱們就可使用 AOP 去組織代碼, 分離 [業務邏輯] 與 [瑣碎事務]axios

AOP 的關鍵概念點

  • 前置(before) 在目標方法執行前執行
  • 後置(after) 在目標方法執行後執行
  • 異常(after throwing)在目標方法拋出異常時執行
  • 環繞 (around) 在目標方法執行先後

前置執行函數

const before = function(fn, action) {
    return function(...args) {
        action.apply(this, args);
        const res = fn.apply(this, args);
        return { res, params: args };
    };
};

後置執行函數

const after = function(fn, action) {
    return function(...args) {
        let res = fn.apply(this, args);
        action.apply(this, args);
        return { res, params: args };
    };
};

異常執行函數

const throwing = function(fn, action) {
    let ret = { res: undefined, params: undefined };
    return function(...args) {
        try {
            const res = fn.apply(this, args);
            return (ret = { res, params: args });
        } catch (err) {
            action.apply(this, args);
            return (ret = { res: err, params: args });
        }
    };
};

環繞執行函數

const round = function(fn, actionBefore, actionAfter) {
    return function(...args) {
        actionBefore.apply(this, args);
        const res = fn.apply(this, args);
        actionAfter.apply(this, args);
        return { res, params: args };
    };
};

使用場景 -- 請求記錄

const request = config => axios.request(config);
  const ButtonClickFn = function () {
    ...do something
  }
  document.querySelector('#submit').click = before(ButtonClickFn, () => {
    request({
      url: 'http://your_upload_log_url',
      method: 'GET',
      params:
        { TYPE: 'BUTTON_CLICK', POSITION: '' }
      });
  });

使用場景 -- 異常處理

const originRequest = config => axios.request(config);
  const wrapperedRequest = throwing(originRequest, function() {
    ...異常上報
  });

其它實現方式

實際上除了使用高階函數的方法實現, 咱們還可使用 ES7 的裝飾器/Ojbect.defineProperty 實現, 或基於原型鏈去實現後端

相關文章
相關標籤/搜索