前言
想必大家对面向对象OOP (Object Oriented Programming)应该都不陌生,它是一种编程思想。而AOP(Aspect Oriented Programming)在编程历史上可以说是里程碑式的,显然它并不是OOP的替代品,而是对OOP的一种十分有益的补充。
那么AOP到底是个啥东西呢?
我们都知道OOP的特点是继承、多态和封装。而封装就是把一个功能的代码封装到一个函数中(或一个类中),以后再想实现这个功能,只需要执行函数方法即可,不需要再重复的编写代码。但这样会有一个问题,假如说我封装了一个选项卡的功能,项目中多处都在使用此功能。突然有一天接到一个需求说希望选项卡切换的时候请求某个接口,这样的话,项目中的每个选项卡都要处理一次这个东西,写一堆代码,是不是就不好了?如果说我只想某几个页面选项卡切换的时候去请求某个接口,那你的业务代码又一堆。所以这个时候就需要切面处理,也就是AOP。
换句大白话,就是说你在家切西瓜,刚切了一刀,突然家里来客人了。。。你就想在西瓜上裱个花,于是就做了一个裱花的函数,但西瓜下面的那些地方,该怎么样还是怎么样。换到代码层面,就是不影响原有的业务逻辑,而又在原有的业务逻辑上做 了一些别的事情。
示例
Function.prototype.before = function(callback) {
let self = this
return function() {
callback()
self.apply(self, arguments)
}
}
function fn(...val) {
console.log('原有功能,' + val)
}
let newFn = fn.before(function() { // 原有功能之前执行
console.log('在原有功能函数之前执行')
})
newFn('准备', '执行') // 为原有功能传参
2020.4.28 (补充)
我们在处理异步并发的时候,可以使用after函数
示例
let fs = require('fs');
let path = require('path');
// 读取文件的路径
let namePath = path.resolve(__dirname, 'name.txt');
let eagPath = path.resolve(__dirname, 'age.txt')
// 用after函数 可以简化异步操作
function after(items, ck) {
let arr = [];
return function(err, data) {
if(err) {
throw new Error(err);
}
arr.push(data); // 把结果传递到对应的callback中
if(--items === 0) {
ck(arr);
}
}
}
let newFn = after(2, function(arr) {
console.log(arr); // 当异步完成后触发
})
/**
* 注意事项:
* 异步不能使用try catch
*/
fs.readFile(namePath, 'utf8', function(err, data) {
newFn(err, data)
})
fs.readFile(eagPath, 'utf8', function(err, data) {
newFn(err, data)
})