爲什麼要介紹RxJs 因爲 在 Nestjs 已經內置了 RxJs 無需安裝 並且Nestjs 也會有一些基於Rxjs提供的API
RxJs是什麼
RxJs 使用的是觀察者模式,用來編寫異步隊列和事件處理。
Observable 可觀察的物件
Subscription 監聽Observable
Operators 純函數可以處理管道的數據 如 map filter concat reduce 等
文檔
案例
發佈訂閱
類似於迭代器 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)
}
})
定時監聽
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()
}
}
)
處理事件
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
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,永不禿頭"
}
}))
}
}
main.ts 中註冊
// 註冊全局響應攔截-格式轉換
app.useGlobalInterceptors(new Response())