NestJS 攔截器 和 RxJs

爲什麼要介紹RxJs 因爲 在 Nestjs 已經內置了 RxJs 無需安裝 並且Nestjs 也會有一些基於Rxjs提供的API

image-20230404093722875

RxJs是什麼

RxJs 使用的是觀察者模式,用來編寫異步隊列和事件處理。

Observable 可觀察的物件

Subscription 監聽Observable

Operators 純函數可以處理管道的數據 如 map filter concat reduce 等

文檔

https://cn.rx.js.org/

案例

發佈訂閱

類似於迭代器 next 發出通知 complete通知完成

subscribe 訂閱 observable 發出的通知 也就是一個觀察者

import { Observable } from "rxjs";
 
//類似於迭代器 next 發出通知  complete通知完成
// 可觀察的物件
const observable = new Observable(subscriber=>{
    // 發出通知
    subscriber.next(1)
    subscriber.next(2)
    subscriber.next(3)
 
    setTimeout(()=>{
        subscriber.next(4)
        subscriber.complete()
    },1000)
})

// 訂閱通知
observable.subscribe({
    // 每一步都可以檢測到
    next:(value)=>{
       console.log(value)
    }
})

image-20230404100417748

定時監聽

interval 五百毫秒執行一次 pipe 就是管道的意思

管道里面也是可以去掉接口的支持處理異步數據

去處理數據 這兒展示 了 map 和 filter 跟數組的方法是一樣的

最後 通過觀察者 subscribe 接受回調

import { interval } from "rxjs";
import { map, filter } from 'rxjs/operators'

// interval 五百毫秒執行一次 pipe 就是管道的意思 
// 管道里面也是可以去掉接口的支持處理異步數據 
const subs = interval(500).pipe(
    map(v => ({ num: v })),
    filter(v => (v.num % 2 == 0))
//通過觀察者 subscribe 接受回調
).subscribe((e) => {
    console.log(e)
    // 結束條件
    if (e.num == 10) {
        subs.unsubscribe()
    }
}
)

image-20230404102025427

處理事件

Rxjs 也可以處理事件

不過我們在Nestjs 裏面就不用操作DOM 了

你如果Angular 或則 Vue 框架看可以使用 fromEvent

import { fromEvent } from "rxjs";
import { map } from 'rxjs/operators'
 
const dom = fromEvent(document,'click').pipe(map(e=>e.target))
dom.subscribe((e)=>{
 
})

攔截器

攔截器具有一系列有用的功能,這些功能受面向切面編程(AOP)技術的啓發。它們可以:

  • 在函數執行之前/之後綁定額外的邏輯
  • 轉換從函數返回的結果
  • 轉換從函數拋出的異常
  • 擴展基本函數行爲
  • 根據所選條件完全重寫函數 (例如, 緩存目的)

文檔:

https://docs.nestjs.cn/9/interceptors

案例:全局響應格式轉換

我們現在沒有給我們的Nestjs 規範返回給前端的格式現在比較亂

就是跟下面一樣

Hello World!

我們想給他返回一個標準的json 格式

就要給我們的數據做一個全局format

{
  data, //數據
  status:0,
  message:"成功",
  success:true
}

那要怎麼實現呢

創建模塊

新建common 文件夾

創建 response.ts

image-20230404103903226

Nest Js 配合 Rxjs 格式化數據

response.ts 中寫入

import { Injectable, NestInterceptor, CallHandler } from '@nestjs/common'
import { map } from 'rxjs/operators'
import { Observable } from 'rxjs'

// 數據
interface data<T> {
  data: T
}

@Injectable()
export class Response<T = any> implements NestInterceptor {
  intercept(context, next: CallHandler): Observable<data<T>> {
    return next.handle().pipe(map(data => {
      return {
        data,
        status: 0,
        success: true,
        message: "makalo 永遠18,永不禿頭"
      }
    }))
  }
}

image-20230404104624742

main.ts 中註冊

// 註冊全局響應攔截-格式轉換
app.useGlobalInterceptors(new Response())

image-20230404104858073

訪問測試

image-20230404105132644

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章