有关NestJS拦截器执行顺序的说明

时间:2019-12-15 18:20:54

标签: nestjs

我有一个返回字符串的控制器处理程序。

// Controller.ts

import { Controller, Get, UseInterceptors } from '@nestjs/common';
import { UpperInterceptor } from './upper.interceptor';
import { LowerInterceptor } from './lower.interceptor';

@Controller()
export class AppController {

  @Get()
  @UseInterceptors(LowerInterceptor, UpperInterceptor)
  getHello(): string {
    return 'Hello'
  }
}

我已经安装了2个拦截器,分别是Lower和Upper,它们确实将字符串大小写更改为其名称。

// lower.interceptor.ts
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'

@Injectable()
export class LowerInterceptor implements NestInterceptor {

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('lower')
    return next
      .handle()
      .pipe(
        map((e) => {
          console.log('calling lowercase')
          return e.toLowerCase()
        }),
      );
  }
}
// upper.interceptor.ts
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'

@Injectable()
export class UpperInterceptor implements NestInterceptor {

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('upper')
    return next
      .handle()
      .pipe(
        map((e) => {
          console.log('calling uppercase')
          return e.toUpperCase()
        }),
      );
  }
}

我希望返回值为HELLO,但返回值为hello

据我所知,首先执行了下层拦截器,但是它传递给可观察对象的映射是在上层拦截器的映射之后执行的,因此返回字符串为hello

您知道为什么拦截器按预期顺序执行,但它们通过管道映射的回调却按相反顺序执行吗?

这与nest还是rxjs有关?抱歉,我都是新手。

1 个答案:

答案 0 :(得分:0)

这是RxJS的东西。 This Stackblitz本质上显示了正在发生的事情,即使未在服务器中明确编写。每个拦截器都链接到下一个拦截器。拦截器遵循“先进先出”堆栈帧,因此您会看到在上位之前记录下位,但是随后看到的输出是小写字母,而不是原来期望的大写字母。我还添加了一些tap方法,以说明在Observbales中发生的一切在呼叫链中的位置。