面向切面编程


面向切面编程Aspect Oriented Programming(AOP),主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中的各部分之间低耦合性的隔离效果。

对程序做无侵入干扰 将来对某些功能进行热插拔 不会影响其他 例如埋点 或者测某些功能性能

// 原始方法 很恶心 每个函数里面去写
// 测函数执行时间
function test() {
    let startTime = new Date().getTime()
    <!--函数功能-->
    console.log('do something')
    return 'test'
    let endTime = new Date().getTime()
    console.log(endTime - startTime)
}
// step1:
Function.prototype.before = function(fn) {
    let self = this
    fn()
    self.apply(this,arguments)
}

Function.prototype.after = function(fn) {
    let self = this
    self.apply(this,arguments)
    fn()
}

test.before(function(){
    console.log('before')
})
test.after(function(){
    console.log('after')
})
问题: 函数执行了2次
test作为中转 暂时先不执行 
before 和before的回调送到 after里面去
after 和 after的回调送到before去
// step2:
改进:
<!--顺序:挂在 self -> test 执行before的回调 执行self  执行after的回调 -->
<!--执行before 不会执行self 而是挂载不执行 -->
Function.prototype.before = function(fn) {
    let self = this
    return function() {
        <!--this指向 ~~~~ windows-->
        <!--self指向 function实例 test -->
        fn.apply(this,arguments) // 为后期改写this
        self.apply(self,arguments)
    }
}

Function.prototype.after = function(fn) {
    let self = this
    return function() {
        // after 先执行本身this 再执行回调
        // 这里的self 其实是before执行后返回的函数 先执行这个 再执行回调
        self.apply(self,arguments)
        fn.apply(this,arguments)
    }
}

test.before(function(){
    console.log('before')
}).after(function(){
    console.log('after')
})()
// step3:
改进:
 // 1.加上更加复杂的验证 假如before 返回false 不再执行
 // 2. 拿到函数本身的返回值
Function.prototype.before = function(fn) {
    let self = this
    return function() {
        if (fn.apply(this,arguments) == false) {
            return false
        }
        return self.apply(self,arguments)
    }
}

Function.prototype.after = function(fn) {
    let self = this
    return function() {
        var result =  self.apply(self,arguments)
        if (result == false) {
            return false
        }
        fn.apply(this,arguments)
        return result
    }
}

test.before(function(){
    console.log('before')
    return false // 假如before回调返回false,则不再执行 
}).after(function(){
    console.log('after')
})()
const timeTaken = callback => {
console.time('timeTaken');  const r = callback();
console.timeEnd('timeTaken');  return r;
};
Last Updated: 4/23/2019, 12:35:34 PM