## 生命周期事件
所有應用程序元素都有一個由 `Nest` 管理的生命周期。`Nest` 提供了**生命周期鉤子**,提供了對關鍵生命時刻的可見性,以及在關鍵時刻發生時采取行動(在你的`module`,`injectable`或者`controller`中注冊代碼)的能力。
### 生命周期序列
下圖描述了關鍵應用生命周期事件序列,從應用引導之時到node應用退出。我們可以把整個生命周期劃分為三個階段:初始化,運行和終止。使用生命周期,你可以合理計劃模塊和服務的初始化,管理活動鏈接,并且在應用程序收到終止指令時優雅地退出。

### 生命周期事件
生命周期事件在應用初始化與終止時發生。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?