import { format } from 'date-fns';
function logDecorator(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
if (typeof originalMethod === 'function') {
if (originalMethod.constructor.name === 'AsyncFunction') {
descriptor.value = async function (...args: any[]) {
const startTime = new Date();
const startFormatted = format(startTime, 'yyyy-MM-dd HH:mm:ss');
console.log(`调用时间: ${startFormatted}, 参数信息: ${JSON.stringify(args)}`);
try {
const result = await originalMethod.apply(this, args);
console.log(`执行结果: ${JSON.stringify(result)}`);
return result;
} catch (error) {
console.log(`执行出错: ${JSON.stringify(error)}`);
throw error;
}
};
} else {
descriptor.value = function (...args: any[]) {
const startTime = new Date();
const startFormatted = format(startTime, 'yyyy-MM-dd HH:mm:ss');
console.log(`调用时间: ${startFormatted}, 参数信息: ${JSON.stringify(args)}`);
try {
const result = originalMethod.apply(this, args);
console.log(`执行结果: ${JSON.stringify(result)}`);
return result;
} catch (error) {
console.log(`执行出错: ${JSON.stringify(error)}`);
throw error;
}
};
}
}
return descriptor;
}
// 同步函数示例
class SyncClass {
@logDecorator
syncMethod(a: number, b: number) {
return a + b;
}
}
// 异步函数示例
class AsyncClass {
@logDecorator
async asyncMethod(a: number, b: number) {
return a + b;
}
}
// 处理不同类型函数的差异:
// 1. **异步函数**:通过判断函数是否为 `AsyncFunction`,如果是则使用 `await` 等待异步操作完成,以确保能正确记录执行结果。
// 2. **同步函数**:直接调用原函数并记录结果。
// 3. **类方法**:在装饰器内部通过 `apply` 方法将 `this` 上下文正确传递给原函数,确保类方法的执行环境正确。这样无论原函数是同步还是异步,都能正确处理并记录日志。