nestjs 全栈进阶--拦截器

视频教程

23_nestjs中的拦截器_哔哩哔哩_bilibili

1. rxjs 介绍

RxJS(Reactive Extensions for JavaScript)是一款专为JavaScript和TypeScript设计的响应式编程库,它遵循ReactiveX规范,提供了一套强大的工具和API,用于处理异步数据流和事件驱动编程。RxJS引入了可观察对象(Observable)的概念,这是一种可以推送多个值、错误或完成通知的数据源。

RxJS的核心特性包括:

  1. Observable:可观察对象是RxJS中最基本的数据类型,它代表了未来可能发出0个或多个值的异步数据流。开发者可以通过订阅(subscribe)Observable来消费它的值,订阅过程中可以指定处理值(next handler)、错误(error handler)和完成(complete handler)的回调函数。
  2. 操作符(Operators) :RxJS有一系列丰富的操作符,可以用来变换、组合、过滤、聚合Observable发出的值。例如,map用于将值映射到另一个值,filter用于筛选满足条件的值,merge用于合并多个Observable的输出,switchMap用于基于当前值切换到另一个Observable等。
  3. 组合能力:RxJS能够将多个异步操作无缝地串联起来,形成复杂的异步流水线,使得代码更加清晰和易于理解。通过操作符可以处理多个异步事件流的并发和依赖关系。
  4. 响应式编程:RxJS有助于实现响应式编程模式,这种模式下,数据流被视为时间和空间上的变化,并可以实时地反应这些变化。无论是用户界面事件、网络请求、计时器事件还是其他任何产生异步数据的源头,都能抽象成Observable,进而采用统一的方式进行处理。
  5. 错误处理和背压支持:RxJS提供了良好的错误处理机制,当Observable遇到错误时,可以通过错误处理器进行恰当的应对。另外,对于高频率数据流,RxJS也支持背压(Backpressure),防止消费者来不及处理生产者产生的大量数据而导致内存溢出等问题。

中文网站地址:rxjs.tech/

有兴趣的话,大家可以自己去看看。我们这主要讲nest拦截器中用到的rxjs

2. 创建项目

arduino 复制代码
nest new interceptor -p pnpm

3. 响应拦截器

css 复制代码
nest g interceptor response --flat --no-spec

生成的代码

我们修改一下

kotlin 复制代码
import { Injectable, NestInterceptor, CallHandler, ExecutionContext } from '@nestjs/common'
import { map } from 'rxjs/operators'
import type { Observable } from 'rxjs';

interface data<T> {
  data: T
}

@Injectable()
export class ResponseIntercept<T = any> implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<data<T>> {
    return next.handle().pipe(map(data => {
      return {
        data,
        code: 200,
        message: "success"
      }
    }))
  }
}

注:map:对响应数据做修改,一般都是改成 {code, data, message} 的格式

我们可以路由级别启用

还可以全局启用,记得注释掉刚刚路由启用的拦截器

路由级别和全局级别的 拦截器 的区别,路由级别的可以注入依赖,而全局的不行,全局 拦截器 可以通过 APP_INTERCEPTOR 的 token 声明,这种能注入依赖,比 app.useGlobalInterceptors 更好。(前面aop时有讲到)

4. 超时拦截器

接口如果长时间没返回,就给用户一个接口超时的响应

css 复制代码
nest g interceptor timeout --flat --no-spec
typescript 复制代码
import { CallHandler, ExecutionContext, Injectable, NestInterceptor, RequestTimeoutException } from '@nestjs/common';
import { catchError, Observable, throwError, timeout, TimeoutError } from 'rxjs';

@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      timeout(3000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          console.log('Timeout error!');

          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      })
    )
  }
}

timeout 操作符会在 3s 没收到消息的时候抛一个 TimeoutError。然后用 catchError 操作符处理下,如果是 TimeoutError,就返回 RequestTimeoutException,这个有内置的 exception filter 会处理成对应的响应格式。

大家注意,如果有的浏览器可能会触发多次

  • timeout:处理响应超时的情况,抛出一个 TimeoutError,配合 catchErrror 可以返回超时的响应
  • catchError:在 exception filter 之前处理抛出的异常,可以记录或者抛出别的异常
相关推荐
qq_17448285758 小时前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
锅包肉的九珍8 小时前
Scala的Array数组
开发语言·后端·scala
心仪悦悦8 小时前
Scala的Array(2)
开发语言·后端·scala
2401_882727579 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
心仪悦悦9 小时前
Scala中的集合复习(1)
开发语言·后端·scala
代码小鑫10 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
真心喜欢你吖10 小时前
SpringBoot与MongoDB深度整合及应用案例
java·spring boot·后端·mongodb·spring
激流丶10 小时前
【Kafka 实战】Kafka 如何保证消息的顺序性?
java·后端·kafka
uzong11 小时前
一个 IDEA 老鸟的 DEBUG 私货之多线程调试
java·后端
飞升不如收破烂~11 小时前
Spring boot常用注解和作用
java·spring boot·后端