前端要懂的AOP面向切面编程(附代码)

492 阅读2分钟

大家好,我是摆烂工程师,今天不摆烂,点杯卡布奇诺,坐下来写一遍关于AOP编程思想的文章。关于AOP的编程,不管在前端还是后端,甚至算法中,都能看到它的身影。我相信大家都写出过这样子的代码。

AOP全称是Aspect Oriented Program, 也就是面向切面编程的意思。字面意思还是比较抽象,我们先来看一小段代码。

const originAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (type, listener, opts) {
    const wrapperListener = function (...args) {
        console.log('练习两年半,真是泰裤辣!');
        return listener.apply(this, args);
    }
    return originAddEventListener.call(this, type, wrapperListener, opts);
}

上面的代码是对一个事件函数进行拦截,再做一层处理。现在我们可以随便给一个DOM元素绑定一个监听事件。触发事件后,都会输出练习两年半,真是泰裤辣!的日志。 而这个对原型链的拦截操作,就是所谓的AOP编程。上面的代码说白了就是在真正的事件执行前,做一些前置操作。而AOP编程,不仅可以做前置操作,还可以做后置操作。也就是代码执行完,还可以在代码后面再做一些其他的处理,比如埋点

如果你碰到过一个场景,也就是事件监听无法捕获到发生跨域后的错误信息时,那么可以对要执行的函数进行一层try...catch...的封装,如下:

const originAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (type, listener, opts) {
    const wrapperListener = function (...args) {
        try {
            return listener.apply(this, args);
        } catch (err) {
            throw err;
        }
    }
    return originAddEventListener.call(this, type, wrapperListener, opts);
}

上面是前端的AOP编程的小栗子,而平时经常使用AOP的场景更多的是在后端,如Java的注解Nest.js的装饰器。这些就是用到AOP编程思想的产物。

比如,我们要设计一个权限点控制的功能。那么我们的功能执行之前,是不是要做这个权限点检查呢,而这个权限点检查,就可以通过AOP的编程思想去处理。权限点检查通过执行功能,权限点不通过就报错403等。流程和AOP的行为如图:

image.png

而上图的装饰器处理的事情就是AOP切面编程处理的事情。在进入管理员功能之前,做好这些检查。

function right(target, key, descriptor) {
    const originFn = descriptor.value;
    if (typeof originFn === 'function') {
        descriptor.value = async function() {
            // 权限检查之后再决定执行功能不。
            if (有权限) {
                return await originFn.apply(this, arguments);
            }
            throw 无权限;
        }
    }
    return descriptor;
}
class LoginController {
    @right('manage')
    manage() {
        // doing some operations...
    }
}

@right就是处理这个权限的装饰器。不止可以处理权限,还可以处理一下接口缓存等。

上面就是一些AOP切面编程的简单例子。看了这些例子,有没有发现AOP切面编程就是简简单单啦。今天差不多就到这里了,我是摆烂工程师,适当摆烂,让生活靠近你。