nest.js 生命周期事件——迹忆客-ag捕鱼王app官网
所有应用程序元素都有一个由 nest 管理的生命周期。nest 提供了生命周期钩子,提供了对关键生命时刻的可见性,以及在关键时刻发生时采取行动(在你的module,injectable或者controller中注册代码)的能力。
生命周期事件
生命周期事件在应用初始化与终止时发生。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()方法,如下:
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异步方法)。
async onmoduleinit(): promise {
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"
}
}