iT邦幫忙

2021 iThome 鐵人賽

DAY 7
0
Modern Web

NestJS 帶你飛!系列 第 7

[NestJS 帶你飛!] DAY07 - Provider (下)

匯出自訂 Provider

在介紹共享模組的時候,有提到可以透過 Module 的 exports 將 Provider 匯出,那自訂 Provider 要如何匯出呢?這部分可以透過一些小技巧來達成。先建立一個 HandsomeModule 來做測試:

$ nest generate module handsome

接著,我們把 Custom Provider 的 展開式用變數儲存起來,再將該展開式放到 providersexports 中:

import { Module } from '@nestjs/common';

const HANDSOME_HAO = {
  provide: 'HANDSOME_MAN',
  useValue: {
    name: 'HAO'
  }
};

@Module({
  providers: [
    HANDSOME_HAO
  ],
  exports: [
    HANDSOME_HAO
  ]
})
export class HandsomeModule {}

AppModule 進行匯入,下方為 app.module.ts 的範例:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { HandsomeModule } from './handsome/handsome.module';

@Module({
  imports: [HandsomeModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

修改 app.controller.ts 查看結果,會在終端機看到:

{ name: 'HAO' }

非同步 Provider

有時候可能需要等待某些非同步的操作來建立 Provider,比如:需要與資料庫連線,Nest App 會等待該 Provider 建立完成才正式啟動。這邊以上方的範例來做修改,調整一下 handsome.module.ts 的內容:

import { Module } from '@nestjs/common';

const HANDSOME_HAO = {
  provide: 'HANDSOME_MAN',
  useFactory: async () => {
    const getHAO = new Promise(resolve => {
      setTimeout(() => resolve({ name: 'HAO' }), 2000);
    });
    const HAO = await getHAO;
    return HAO;
  }
};

@Module({
  providers: [
    HANDSOME_HAO
  ],
  exports: [
    HANDSOME_HAO
  ]
})
export class HandsomeModule {}

在等待兩秒後,終端機會出現下方結果:

{ name: 'HAO' }

自選式 Provider

有時候可能會有 Provider 沒有被提供但卻注入的情況,這樣在啟動時會報錯,因為 Nest 找不到對應的 Provider,那遇到這種情況該如何處理呢?首先,遇到這類型情況通常會給個預設值代替沒被注入的 Provider,然後要在注入的地方添加 @Optional 裝飾器。這裡我們同樣沿用上方範例,去修改 app.module.ts 的內容,將 HandsomeModule 移除匯入:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

接著去修改 app.controller.ts 的內容,替 HANDSOME_MAN 給定預設值:

import { Controller, Get, Inject, Optional } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(
    private readonly appService: AppService,
    @Optional() @Inject('HANDSOME_MAN') private readonly handsomeMan = { name: '' }
    ) {
      console.log(this.handsomeMan);
  }

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

此時的終端機會顯示結果:

{ name: '' }

小結

今天的內容主要是針對 Provider 的一些小技巧做介紹,下方為懶人包:

  1. 自訂 Provider 可以透過把展開式抽離至變數來進行匯出。
  2. Provider 支援非同步建立,在尚未建立完 Provider 以前,Nest App 不會正式啟動。
  3. 如果 Provider 並不是必須項目,必須在注入的地方添加 @Optional,這邊也建議替該參數設置預設值。

在了解完 Nest 鐵三角之後,就可以開始介紹一些其他的功能了!那就明天見囉!


上一篇
[NestJS 帶你飛!] DAY06 - Provider (上)
下一篇
[NestJS 帶你飛!] DAY08 - Exception & Exception filters
系列文
NestJS 帶你飛!32

尚未有邦友留言

立即登入留言