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 之前处理抛出的异常,可以记录或者抛出别的异常
相关推荐
假装我不帅1 小时前
asp.net framework从webform开始创建mvc项目
后端·asp.net·mvc
神仙别闹1 小时前
基于ASP.NET+SQL Server实现简单小说网站(包括PC版本和移动版本)
后端·asp.net
计算机-秋大田2 小时前
基于Spring Boot的船舶监造系统的设计与实现,LW+源码+讲解
java·论文阅读·spring boot·后端·vue
货拉拉技术2 小时前
货拉拉-实时对账系统(算盘平台)
后端
掘金酱3 小时前
✍【瓜分额外奖金】11月金石计划附加挑战赛-活动命题发布
人工智能·后端
代码之光_19803 小时前
保障性住房管理:SpringBoot技术优势分析
java·spring boot·后端
ajsbxi3 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
颜淡慕潇4 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
尘浮生5 小时前
Java项目实战II基于Spring Boot的光影视频平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·maven·intellij-idea