前言
本文是基于小满zs的nest教学视频的个人学习笔记,大家感兴趣可以去看看原文
xiaoman.blog.csdn.net/article/det…
我们通过axios库发送http请求,首先安装axios
1 | sh复制代码npm i axios -S |
然后定义一个控制器 Controller
1 | ts复制代码class Controller { |
现在我希望Controller的getList()方法可以获取后端API返回的list,同时通过装饰器@GET去发送http请求,getList()方法中不包含任何与网络请求有关的代码。
那么我们要做的第一步,将后端API的URL作为参数传入装饰器函数中,再由装饰器函数发起axios请求,按照正常人想法,既然装饰器本质是一个函数,那我能不能直接将URL作为参数,传入装饰器函数中呢?
1 | ts复制代码const GET:MethodDecorator = (target, key, scriptor, URL:string)=>{ |
可以发现代码报错,MethodDecorator函数类型的参数是固定的,不能随便添加。
因为TS严格约束数据类型,因此通过|来添加参数的方法并不可取,至少这种投机取巧的方式用的多了,项目便很难维护。所以现在,是高阶函数出场的时候了。
既然我们要将URL作为参数传入装饰器函数,但是装饰器函数不能接收新的参数。我们不妨在外面再套一层函数,最外面的一层函数接收URL,然后返回装饰器函数。由于装饰器函数引用了外层函数的URL,形成了一个闭包!我们的问题完美解决了
1 | ts复制代码const GET = (URL: string):MethodDecorator=>{ |
这种高阶函数就叫做装饰器工厂,装饰器的本质就是一个高阶函数。
接下来我们就可以继续编写装饰器函数中的逻辑:发送HTTP Get请求,然后将结果返回给装饰的getList()函数
这里我们复习一下方法装饰器函数的三个默认参数
- 原型对象
- 方法名称
- 属性描述符
- 可写:writable
- 可枚举:enumerable
- 可配置:configurable
- ?value:对应的函数
所以我们可以通过descriptor属性描述符的value属性,获取到装饰的函数
1 | ts复制代码import axios from "axios"; |
然后我们使用@Get装饰getList方法,然后再getList函数里接收返回的参数。这句话是什么意思呢?我来解释给你听:
我们再axios发起Get请求后,调用了fn()函数,并往里面传递了一系列参数
1 | ts复制代码 axios.get(url).then(res => { |
而fn()函数是我们从方法装饰器的属性描述符中获取的
1 | ts复制代码 //获取到装饰的函数 |
结合起来就是,fn()函数接收到的参数,会传递给原方法,即被getList()函数接收
1 | ts复制代码class Controller { |
这样通过装饰器实现了,将发送HTTP Get请求的逻辑全部集中到@GET返回的装饰器函数,将Get请求返回的结果处理逻辑,全部集中到了getlist()方法中。
总结
我们通过定义装饰器工厂函数(高阶函数),解决了向装饰器传递自定义参数的问题
通过装饰器,成功将发送Get请求逻辑和处理Get请求逻辑分开
本文转载自: 掘金