如何在TypeScript文件中调用NestJS服务函数?实例化报错求助
NestJS定时任务调用服务函数的正确实现
问题根源
你手动通过new SslService()和new SslCronJob(sslService)实例化服务的方式,完全绕过了Nest的依赖注入容器。SslService内部依赖的模型、数据库连接等资源没有被Nest初始化,导致执行时无法访问模型属性。
正确实现步骤
1. 注册定时任务类到模块
在对应的业务模块(比如SslModule)中,将SslCronJob添加到providers数组,让Nest的DI容器管理它的实例:
@Module({ providers: [SslService, SslCronJob], // 若需在其他模块调用,可添加exports: [SslCronJob] }) export class SslModule {}
2. 从Nest容器获取实例启动任务
在main.ts中,不要手动实例化服务,而是通过Nest应用容器获取SslCronJob的实例:
async function bootstrap() { const app = await NestFactory.create(AppModule); // 从DI容器中获取已初始化的SslCronJob实例 const sslCronJob = app.get(SslCronJob); await sslCronJob.upload(); await app.listen(3000); } bootstrap();
3. (推荐)用生命周期钩子自动启动任务
更符合Nest规范的做法是利用OnModuleInit生命周期钩子,让模块初始化时自动启动定时任务,无需在main.ts手动调用:
修改SslCronJob类:
import { Injectable, OnModuleInit } from '@nestjs/common'; import { SslService } from './ssl.service'; import * as cron from 'node-cron'; @Injectable() export class SslCronJob implements OnModuleInit { constructor( private readonly sslService: SslService ) {} async onModuleInit() { // 模块初始化完成后注册定时任务 cron.schedule('* * * * *', async () => { console.log('running a task every minute'); try { await this.sslService.upload(); } catch (err) { console.error('定时任务执行失败:', err); } }); } }
这样配置后,Nest会在模块加载完成后自动执行onModuleInit方法,启动定时任务,无需在main.ts额外处理。
关键说明
Nest的依赖注入容器会自动处理服务的依赖链:如果SslService依赖了数据库Repository或其他服务,Nest会递归实例化所有依赖并注入。手动实例化会跳过这个过程,导致服务内部依赖为undefined,最终引发无法访问模型属性的错误。
内容的提问来源于stack exchange,提问作者Kevin Corona
相关产品推荐
相关产品推荐

