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 之前处理抛出的异常,可以记录或者抛出别的异常
相关推荐
SomeB1oody8 分钟前
【Rust自学】7.4. use关键字 Pt.2 :重导入与换国内镜像源教程
开发语言·后端·rust
新知图书12 分钟前
Rust编程与项目实战-箱
开发语言·后端·rust
SomeB1oody16 分钟前
【Rust自学】7.3. use关键字 Pt.1:use的使用与as关键字
开发语言·后端·rust
minstbe26 分钟前
WEB开发 - Flask 入门:Jinja2 模板语法进阶 Python
后端·python·flask
无名之逆1 小时前
lombok-macros
开发语言·windows·后端·算法·面试·rust·大学期末
m0_748247801 小时前
SpringBoot集成Flowable
java·spring boot·后端
散一世繁华,颠半世琉璃1 小时前
SpringBoot揭秘:URL与HTTP方法如何定位到Controller
spring boot·后端·http
安晴晚风2 小时前
从0开始在linux服务器上部署SpringBoot和Vue
linux·运维·前端·数据库·后端·运维开发
海绵波波1078 小时前
flask后端开发(10):问答平台项目结构搭建
后端·python·flask
网络风云10 小时前
【魅力golang】之-反射
开发语言·后端·golang