## 生命周期事件
所有应用程序元素都有一个由 `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()`钩子,所以如果有一些间隔,长时间运行的后台任务等,该进程不会自动终止。
- 介绍
- 概述
- 第一步
- 控制器
- 提供者
- 模块
- 中间件
- 异常过滤器
- 管道
- 守卫
- 拦截器
- 自定义装饰器
- 基础知识
- 自定义提供者
- 异步提供者
- 动态模块
- 注入作用域
- 循环依赖
- 模块参考
- 懒加载模块
- 应用上下文
- 生命周期事件
- 跨平台
- 测试
- 技术
- 数据库
- Mongo
- 配置
- 验证
- 缓存
- 序列化
- 版本控制
- 定时任务
- 队列
- 日志
- Cookies
- 事件
- 压缩
- 文件上传
- 流式处理文件
- HTTP模块
- Session(会话)
- MVC
- 性能(Fastify)
- 服务器端事件发送
- 安全
- 认证(Authentication)
- 授权(Authorization)
- 加密和散列
- Helmet
- CORS(跨域请求)
- CSRF保护
- 限速
- GraphQL
- 快速开始
- 解析器(resolvers)
- 变更(Mutations)
- 订阅(Subscriptions)
- 标量(Scalars)
- 指令(directives)
- 接口(Interfaces)
- 联合类型
- 枚举(Enums)
- 字段中间件
- 映射类型
- 插件
- 复杂性
- 扩展
- CLI插件
- 生成SDL
- 其他功能
- 联合服务
- 迁移指南
- Websocket
- 网关
- 异常过滤器
- 管道
- 守卫
- 拦截器
- 适配器
- 微服务
- 概述
- Redis
- MQTT
- NATS
- RabbitMQ
- Kafka
- gRPC
- 自定义传输器
- 异常过滤器
- 管道
- 守卫
- 拦截器
- 独立应用
- Cli
- 概述
- 工作空间
- 库
- 用法
- 脚本
- Openapi
- 介绍
- 类型和参数
- 操作
- 安全
- 映射类型
- 装饰器
- CLI插件
- 其他特性
- 迁移指南
- 秘籍
- CRUD 生成器
- 热重载
- MikroORM
- TypeORM
- Mongoose
- 序列化
- 路由模块
- Swagger
- 健康检查
- CQRS
- 文档
- Prisma
- 静态服务
- Nest Commander
- 问答
- Serverless
- HTTP 适配器
- 全局路由前缀
- 混合应用
- HTTPS 和多服务器
- 请求生命周期
- 常见错误
- 实例
- 迁移指南
- 发现
- 谁在使用Nest?