首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >类装饰器Nestjs修改类中的每个方法

类装饰器Nestjs修改类中的每个方法
EN

Stack Overflow用户
提问于 2022-07-17 06:31:40
回答 1查看 730关注 0票数 2

我想要创建一个装饰器,它将获取一个类的所有方法,并使用特定的功能包装它们,在这个例子中,只需要这样记录:

代码语言:javascript
运行
复制
export function CustDec<T extends new (...args: any[]) => any>(Target: T) {
  return class extends Target {
    constructor(...args: any[]) {
      super(...args);
      console.log('@--------------------@');
      (Target as any).prototype.alphaMethod = async (args: any[]) => {
        console.log('@-before-@');
        await (Target as any).alphaMethod();
        console.log('@-after-@');
      };
    }
  };
}

问题是,当我将这个装饰器应用于我的类时:

代码语言:javascript
运行
复制
import { Controller, Post } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { Firewall } from 'src/auth/decorators/firewall.decorator';
import { CustDec } from './feedback.decorator';

@CustDec
@ApiTags('feedback')
@Controller('feedback')
export class FeedbackController {
  constructor() {
    setTimeout(async () => {
      await this.alphaMethod(); // <--- here
    }, 3000);
  }

  @Firewall()
  @Post('')
  async alphaMethod() { // <-- and here
    return 'some promised result';
  }
}

当我试图在控制器上调用/feedback端点时,我会得到一个错误,好像FirewallPost装饰器在Firewall更改了alphaMethod之后停止了工作。即使我从我的alphaMethod构造函数方法中调用FeedbackController,我也会得到另一个错误:

代码语言:javascript
运行
复制
@-before-@
This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason:
TypeError: Target.alphaMethod is not a function
    at FeedbackController.Target.alphaMethod (/home/zagrava/workspace/test-nest/backend/src/feedback/feedback.decorator.ts:8:31)
    at Timeout._onTimeout (/home/zagrava/workspace/test-nest/backend/src/feedback/feedback.controller.ts:12:18)
    at listOnTimeout (node:internal/timers:564:17)
    at processTimers (node:internal/timers:507:7)

如何使我的CustDec用日志正确包装类的所有方法?

EN

回答 1

Stack Overflow用户

发布于 2022-07-17 07:37:15

类装饰器可以实现如下所示:

代码语言:javascript
运行
复制
function intercept<T extends { new(...args: any[]): {} }>(target: T) {
  const methods = getMethods(target.prototype);
  for (const method of methods) {
    const currentMethod = target.prototype[method]
    target.prototype[method] = async (...args: any[]) => {
      console.log("intercepted", new Date());
      const result = currentMethod(args)
      if (result instanceof Promise) {
        await result
      }
      console.log("executed", new Date());
      return result;
    }
  }
}

其思想是获取类的所有函数(构造函数本身除外),并将它们包装在自定义函数中。在这种情况下,获得类的函数的助手方法是有用的:

代码语言:javascript
运行
复制
const getMethods = (obj: any) => Object.getOwnPropertyNames(obj).filter(item => typeof obj[item] === 'function' && item !== "constructor")

游乐场

多个装潢师在行动中

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73009667

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档