装饰器

装饰器

老师,你好。

import { GlobalErrorType } from '../error'
import { Controller } from 'egg'

/**
 * 创建工厂函数接收 rules 和 errorType
 * @param rules 验证规则
 * @param errorType 错误类型
 */
export default function validateInput(rules: any, errorType: GlobalErrorType) {
  /**
   * @param _prototype 原型对象
   * @param _key 属性名称
   * @param descriptor 属性描述符
   */
  return function(_prototype, _key: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value // 获取属性对应的值(函数体)

    // 重写被装饰的函数
    descriptor.value = function(...args: any[]) {
      const that = this as Controller
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      const { ctx, app } = that
      const error = app.validator.validate(rules, ctx.request.body)
      if (error) {
        return ctx.helper.error({ctx, errorType, error})
      }

	 // 为什么这里不返回就会出问题?
      return originalMethod.apply(this, args)
    }
  }
}

请问为什么不返回 originalMethod.apply(this, args) 就会出问题?

正在回答

登陆购买课程后可参与讨论,去登陆

1回答

同学你好

因为 originalMethod.apply(this, args) 是原始方法真正的执行啊

如果不加这一行,那么被装饰的函数真正的函数体就不会执行,只会执行添加上去的装饰的一部分逻辑,这样就会出现问题。

  • 慕粉3946981 提问者 #1

    是这个 return 语句有些不理解,我这边本地测试了,如果没有这个return语句被装饰的控制器就会出现问题,不理解这是为什么。

     return originalMethod.apply(this, args) // 有 return 那么这个被装饰的控制器就没有问题
    originalMethod.apply(this, args) // 没有 return 那么这个被装饰的控制器就会出现问题


    2022-12-30 14:21:01
  • 张轩 回复 提问者 慕粉3946981 #2

    装饰器本身应该是没有说必须要return 这个规则,针对我们这个全异步应用就需要返回了,要不异步走不下去,程序会直接中断报错,或者你也可以使用 await

    await originalMethod.apply(this, args)

    这样也可以。

    2022-12-31 16:55:25
  • 慕粉3946981 提问者 回复 张轩 #3

    明白了,多谢指点。

    2023-01-02 09:48:58
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师