企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## 生命周期事件 所有应用程序元素都有一个由 `Nest` 管理的生命周期。`Nest` 提供了**生命周期钩子**,提供了对关键生命时刻的可见性,以及在关键时刻发生时采取行动(在你的`module`,`injectable`或者`controller`中注册代码)的能力。 ### 生命周期序列 下图描述了关键应用生命周期事件序列,从应用引导之时到node应用退出。我们可以把整个生命周期划分为三个阶段:初始化,运行和终止。使用生命周期,你可以合理计划模块和服务的初始化,管理活动链接,并且在应用程序收到终止指令时优雅地退出。 ![生命周期钩子](https://docs.nestjs.com/assets/lifecycle-events.png) ### 生命周期事件 生命周期事件在应用初始化与终止时发生。Nest在`modules`,`injectables`和`controllers`的以下每个生命周期事件(首先要使能shutdown钩子,如下描述)中调用注册钩子方法。和上图所示的一样,Nest也调用合适的底层方法来监听连接,以及终止监听连接。 在下述表格中,`onModuleDestroy`, `beforeApplicationShutdown`和 `onApplicationShutdown`仅仅在显式调用`app.close()`或者应用收到特定系统信号(例如 SIGTERM)并且在初始化时(参见下表的应用`shutdown`部分)正确调用了`enableShutdownHooks`方法后被触发。 |生命周期钩子方法|生命周期时间触发钩子方法调用| | ------------------------ | ----------------------------------------------- | | `OnModuleInit()` | 初始化主模块依赖处理后调用一次| | `OnApplicationBootstrap()` | 在应用程序完全启动并监听连接后调用一次| | `OnModuleDestroy()` | 收到终止信号(例如SIGTERM)后调用 | |`beforeApplicationShutdown()`|在`onModuleDestroy()`完成(Promise被resolved或者rejected);一旦完成,将关闭所有连接(调用app.close() 方法).| | `OnApplicationShutdown()` | 连接关闭处理时调用(app.close())| > 上述列出的生命周期钩子没有被请求范围类触发。请求范围类并没有和生命周期以及不可预测的寿命绑定。他们为每个请求单独创建,并在响应发送后通过垃圾清理系统自动清理。 ### 使用 所有应用周期的钩子都有接口表示,接口在技术上是可选的,因为它们在 `TypeScript` 编译之后就不存在了。尽管如此,为了从强类型和编辑器工具中获益,使用它们是一个很好的实践。要注册生命周期挂钩,请实现适当的接口。例如,要注册一个方法在特定类(例如,控制器,提供者或者模块)初始化时调用,使用`OnModuleInit`接口,提供`onModuleInit()`方法,如下: ```typescript import { Injectable, OnModuleInit } from '@nestjs/common'; @Injectable() export class UsersService implements OnModuleInit { onModuleInit() { console.log(`The module has been initialized.`); } } ``` ### 异步初始化 此外,`OnModuleInit` 和 `OnApplicationBootstrap` 钩子都允许您延迟应用程序初始化过程(返回一个`Promise`或在方法主体中将方法标记为`async`和`await`异步方法)。 ```typescript async onModuleInit(): Promise<void> { await this.fetch(); } ``` ### 应用程序关闭[#](#application-shutdown) `onModuleDestroy()`, `beforeApplicationShutdown()`和 `onApplicationShutdown()`钩子程序响应系统终止信号(当应用程序通过显示调用`app.close()`或者收到`SIGTERM`系统信号时),以优雅地关闭 `Nest` 应用程序。这一功能通常用于 `Kubernetes` 、`Heroku` 或类似的服务。 系统关闭钩子消耗系统资源,因此默认是禁用的。要使用此钩子,必须通过`enableShutdownHooks()`激活侦听器。 ```typescript import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); // Starts listening to shutdown hooks app.enableShutdownHooks(); await app.listen(3000); } bootstrap(); ``` > 由于平台限制,NestJs的关闭钩子在Windows下有一些限制。`SIGINT`,`SIGBREAK`以及一些`SIGHUP`信号可以工作--[阅读更多](https://nodejs.org/api/process.html#process_signal_events)。然而,`SIGTERM`永远不会在Windows下工作,因为在任务管理器中终止进程是无条件的。“即,应用没有办法发现或者阻止它”。一些Windows下关于`SIGINT`和`SIGBREAK`的libuv的[相关文档](https://docs.libuv.org/en/v1.x/signal.html)。参见Nodejs的[线程信号事件](https://nodejs.org/api/process.html#process_signal_events)文档。 > `enableShutdownHooks`开始监听时消耗内存。如果要在一个单独Node线程中运行多个Nest应用(例如,使用多个Jest运行测试),Node会抱怨监听者太多。出于这个原因,`enableShutdownHooks`默认未启用。要在单个Node进程中运行多个实例时尤其要注意这一点。 如果应用程序接收到一个终止信号,它将会依次调用注册的`onModuleDestroy()`, `beforeApplicationShutdown()`和`onApplicationShutdown()`方法,将响应信号作为第一个参数。如果一个注册函数等待异步调用(作为promise),那么在 `promise` 被解析或拒绝之前,它不会关闭 Nest 应用程序。 ```typescript @Injectable() class UsersService implements OnApplicationShutdown { onApplicationShutdown(signal: string) { console.log(signal); // e.g. "SIGINT" } } ``` >**信息**:调用`app.close()`不会终止Node进程,只会触发`onModuleDestroy()`和`onApplicationShutdown()`钩子,所以如果有一些间隔,长时间运行的后台任务等,该进程不会自动终止。