参考资料:
异步本地存储 |NestJS - 渐进式 Node.js 框架我们可以使用AsyncLocalStorage,实现类似Java语言中的ThreadLocal变量,从而在整个线程范围内扩散对象和数据,而无需在方法参数列表中传递对象。例如实现类似 SpringBoot中RequestContextHolder类似的效果。
首先创建 als.module.ts,这个是类似实现一个单例的对象,该对象在单次前端请求整个生命期间有效:
- import { Inject, Injectable, Module } from '@nestjs/common';
- import { AsyncLocalStorage } from 'async_hooks';
- @Module({
- providers: [
- {
- provide: AsyncLocalStorage,
- useValue: new AsyncLocalStorage(),
- },
- ],
- exports: [AsyncLocalStorage],
- })
- export class AlsModule { }
其次,修改 app.module.ts,路由拦截所有请求,并处理相关数据,然后存入 storage:
- import { AlsModule } from './als.module';
- import { AlsLogger } from 'AlsLogger';
- @Module({
- imports: [
- AlsModule,
-
- ],
-
- })
- export class AppModule implements NestModule {
- private readonly logger: Logger = new AlsLogger("AppModule");
- constructor(
- private readonly als: AsyncLocalStorage<object>
- ) { }
- configure(consumer: MiddlewareConsumer) {
-
- consumer.apply((req, res, next) => {
- const token = req.headers['accesstoken'];
- let info = "";
- if (token) {
- const headers = JSON.parse(token);
- info = this.logger.genInfo(headers.a, headers.b, headers.c, headers.d);
- } else {
- info = req.headers['token'] || req.headers['access_token'] || req.headers['access-token'] || this.logger.genInfo("-9", "-9", "-9", "-9");
- }
- const store = { info: info };
- this.als.run(store, () => next());
- }).forRoutes('*');
- }
- }
最后,在任意地方使用:
- import { AsyncLocalStorage } from 'async_hooks';
- @Injectable()
- export class XxxxService {
- constructor(
- private readonly als: AsyncLocalStorage<object>,
-
- ) {}
- async xxx(a: string) {
- const passAlong = this.als.getStore()['passAlong'] as string;
- console.log("我们可以拿到 pass along: ", passAlong);
-
- }
- }
这样我们就可以实现线程全局变量了。