作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个需要依赖注入(inject)的装饰器。例如:
@Injectable()
class UserService{
@TimeoutAndCache(1000)
async getUser(id:string):Promise<User>{
// Make a call to db to get all Users
}
}
@TimeoutAndCache 返回一个新的 promise ,它执行以下操作:
export const TimeoutAndCache = function timeoutCache(ts: number, namespace) {
return function log(
target: object,
propertyKey: string,
descriptor: TypedPropertyDescriptor<any>,
) {
const originalMethod = descriptor.value; // save a reference to the original method
descriptor.value = function(...args: any[]) {
// pre
let timedOut = false;
// run and store result
const result: Promise<object> = originalMethod.apply(this, args);
const task = new Promise((resolve, reject) => {
const timer = setTimeout(() => {
if (!timedOut) {
timedOut = true;
console.log('timed out before finishing');
reject('timedout');
}
}, ts);
result.then(res => {
if (timedOut) {
// store in cache
console.log('store in cache');
} else {
clearTimeout(timer);
// return the result
resolve(res);
}
});
});
return task;
};
return descriptor;
};
};
我需要注入(inject)一个 RedisService 来保存计算结果。我可以将 Redis 服务注入(inject) UserService 的一种方法,但看起来有点丑陋。
最佳答案
您应该考虑使用 Interceptor
而不是自定义装饰器,因为它们在 Nest 管道中运行较早,并且默认支持依赖注入(inject)。
但是,因为您既要传递值(用于缓存超时)又要解决依赖关系,您必须使用 mixin
模式。
import {
ExecutionContext,
Injectable,
mixin,
NestInterceptor,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { TestService } from './test/test.service';
@Injectable()
export abstract class CacheInterceptor implements NestInterceptor {
protected abstract readonly cacheDuration: number;
constructor(private readonly testService: TestService) {}
intercept(
context: ExecutionContext,
call$: Observable<any>,
): Observable<any> {
// Whatever your logic needs to be
return call$;
}
}
export const makeCacheInterceptor = (cacheDuration: number) =>
mixin(
// tslint:disable-next-line:max-classes-per-file
class extends CacheInterceptor {
protected readonly cacheDuration = cacheDuration;
},
);
然后您将能够以类似的方式将拦截器应用于您的处理程序:
@Injectable()
class UserService{
@UseInterceptors(makeCacheInterceptor(1000))
async getUser(id:string):Promise<User>{
// Make a call to db to get all Users
}
}
关于dependency-injection - 如何将依赖注入(inject)与自定义装饰器集成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54283033/
我是一名优秀的程序员,十分优秀!