Nest.js 生命周期事件

所有应用程序元素都有一个由 Nest 管理的生命周期。Nest 提供了生命周期钩子,提供了对关键生命时刻的可见性,以及在关键时刻发生时采取行动(在你的module,injectable或者controller中注册代码)的能力。


生命周期事件

生命周期事件在应用初始化与终止时发生。Nest在 modulesinjectablescontrollers 的以下每个生命周期事件(首先要使能shutdown钩子,如下描述)中调用注册钩子方法。和上图所示的一样,Nest也调用合适的底层方法来监听连接,以及终止监听连接。

在下述表格中,onModuleDestroy, beforeApplicationShutdownonApplicationShutdown 仅仅在显式调用 app.close() 或者应用收到特定系统信号(例如 SIGTERM)并且在初始化时(参见下表的应用shutdown部分)正确调用了enableShutdownHooks方法后被触发。

生命周期钩子方法 生命周期时间触发钩子方法调用
OnModuleInit() 初始化主模块依赖处理后调用一次
OnApplicationBootstrap() 在应用程序完全启动并监听连接后调用一次
OnModuleDestroy() 收到终止信号(例如SIGTERM)后调用
beforeApplicationShutdown() 在onModuleDestroy()完成(Promise被resolved或者rejected);一旦完成,将关闭所有连接(调用app.close() 方法).
OnApplicationShutdown() 连接关闭处理时调用(app.close())

上述列出的生命周期钩子没有被请求范围类触发。请求范围类并没有和生命周期以及不可预测的寿命绑定。他们为每个请求单独创建,并在响应发送后通过垃圾清理系统自动清理。


用例

所有应用周期的钩子都有接口表示,接口在技术上是可选的,因为它们在 TypeScript 编译之后就不存在了。尽管如此,为了从强类型和编辑器工具中获益,使用它们是一个很好的实践。要使用合适的接口。例如,要注册一个方法在特定类(例如,控制器,提供者或者模块)初始化时调用,使用OnModuleInit接口,提供onModuleInit()方法,如下:

import { Injectable, OnModuleInit } from '@nestjs/common';

@Injectable()
export class UsersService implements OnModuleInit {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}

异步初始化

此外,OnModuleInitOnApplicationBootstrap 钩子都允许您延迟应用程序初始化过程(返回一个Promise或在方法主体中将方法标记为async和await异步方法)。

async onModuleInit(): Promise<void> {
  await this.fetch();
}

Application Shutdown

onModuleDestroy() , beforeApplicationShutdown()onApplicationShutdown() 钩子程序响应系统终止信号(当应用程序通过显示调用app.close()或者收到SIGTERM系统信号时),以优雅地关闭 Nest 应用程序。这一功能通常用于 Kubernetes 、Heroku 或类似的服务。

系统关闭钩子消耗系统资源,因此默认是禁用的。要使用此钩子,必须通过enableShutdownHooks()激活侦听器。

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Starts listening for shutdown hooks
  app.enableShutdownHooks();

  await app.listen(3000);
}
bootstrap();

警告 ⚠️ : 由于平台限制,NestJs的关闭钩子在Windows下有一些限制。SIGINT,SIGBREAK以及一些SIGHUP信号可以工作–阅读更多。然而,SIGTERM在Windows下不工作,因为在任务管理器中关闭一个线程是无条件的。“例如,应用没有办法发现或者阻止它”。一些Windows下关于SIGINT和SIGBREAK的libuv的相关文档。参见Nodejs的线程信号事件文档。

提示 :enableShutdownHooks开始监听时消耗内存。如果要在一个单独Node线程中运行多个Nest应用(例如,使用多个Jest运行测试),Node会抱怨监听者太多。出于这个原因,enableShutdownHooks默认未启用。要在单个Node进程中运行多个实例时尤其要注意这一点。

如果应用程序接收到一个终止信号,它将会依次调用注册的onModuleDestroy(), beforeApplicationShutdown()和onApplicationShutdown()方法,将响应信号作为第一个参数。如果一个注册函数等待异步调用(作为promise),那么在 promise 被解析或拒绝之前,它不会关闭 Nest 应用程序。

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal: string) {
    console.log(signal); // e.g. "SIGINT"
  }
}

查看笔记

扫码一下
查看教程更方便