设计方案
- 参数装饰器定义:在TypeScript中,参数装饰器会在运行时被调用,并且传入目标类的原型、方法名以及参数在参数列表中的索引。
- 通用逻辑实现:在装饰器内部,我们可以通过闭包的方式来记录函数调用的参数、时间,并在函数执行前后执行特定逻辑。
- 异步函数处理:使用
async
和await
来处理异步函数,确保在异步操作完成后记录执行结果。
完整代码示例
function logParameter(target: any, propertyKey: string, parameterIndex: number) {
return function (originalMethod: Function) {
return function (...args: any[]) {
const startTime = new Date();
console.log(`Calling function ${propertyKey} at ${startTime.toISOString()}`);
console.log(`Parameter at index ${parameterIndex} is:`, args[parameterIndex]);
const result = originalMethod.apply(this, args);
if (typeof result.then === 'function') {
return result.then((resolvedResult: any) => {
const endTime = new Date();
console.log(`Function ${propertyKey} finished at ${endTime.toISOString()}`);
console.log(`Execution result is:`, resolvedResult);
return resolvedResult;
});
} else {
const endTime = new Date();
console.log(`Function ${propertyKey} finished at ${endTime.toISOString()}`);
console.log(`Execution result is:`, result);
return result;
}
};
};
}
class MyClass {
async myMethod(@logParameter param: string) {
// 模拟异步操作
await new Promise(resolve => setTimeout(resolve, 1000));
return `Processed: ${param}`;
}
}
const myObj = new MyClass();
myObj.myMethod('test').then(console.log);
相较于传统AOP实现方式的优缺点
优点
- 简洁性:TypeScript的装饰器语法糖使得代码更加简洁,逻辑清晰。在上述代码中,通过一个简单的装饰器函数就实现了AOP功能。
- 紧密集成:与TypeScript语言特性紧密结合,在面向对象编程的基础上轻松实现AOP,对于TypeScript项目而言更易维护和扩展。
缺点
- 兼容性:装饰器是ES7的提案,虽然TypeScript支持,但在一些老版本的JavaScript环境中可能不兼容,需要额外的编译或运行时处理。
- 调试难度:由于装饰器通过闭包和函数劫持来实现,在调试复杂的AOP逻辑时,可能需要花费更多精力去理解装饰器内部的执行流程。