日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

combineLatest 使用的一个陷阱和基于 debounceTime 的解决方案

發布時間:2023/12/19 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 combineLatest 使用的一个陷阱和基于 debounceTime 的解决方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先了解 combineLatest 這個操作符的作用:

組合多個 Observable 以創建一個 Observable,其值是根據其每個輸入 Observable 的最新值計算得出的。

其彈珠圖如下圖所示:

我們有一個限制值流和一個偏移值流。 我們使用 combineLatest 組合這些流以創建一個流,該流將在每次源流之一更改時具有一個新值。 然后我們使用 switchMap 根據這些值從后端獲取數據以獲取 pokemon$。 因為我們使用了switchMap,如果一個調用還沒有結束,那么當一個新的調用通過改變limit或者offset來發起一個新的調用時,前一個調用就會被取消。

代碼如下:

this.pokemon$ = combineLatest(limit$, offset$).pipe(map(data => ({limit: data[0], offset: data[1]})),switchMap(data => this.pokemonService.getPokemon(data.limit, data.offset)),map((response: {results: Pokemon[]}) => response.results),);

代碼地址如下:

https://stackblitz.com/edit/angular-deqtkx

當我修改 limit 和 offset 為其他值之后,點擊 reset 按鈕,此時會觀察到先后發起兩個請求,并且第一個請求自動被 cancel 的情況:

通過單擊重置按鈕,我們通過同時重置限制和偏移值來更新我們的兩個源流。 這個動作的效果是 combineLatest 創建的流觸發了兩次,因此啟動了兩個后端請求,另一方面,由于我們使用了 switchMap,立即取消了一個。

我們來單步拆解,以加深印象:

  • combineLatest 保存所有源流的最后一個值。比如開始場景是,limit = 8,offset = 2)
  • 單擊重置按鈕
  • limit 設置為 5
  • combineLatest 看到一個新值進入 limit 并發出一個新組合,limit = 5,offset = 2
  • switchMap 獲取這些值并訂閱觸發后端調用的流
    偏移量設置為 0
  • combineLatest 看到一個新的 offset 值,并發出一個新的組合,limit = 5,offset = 0
  • switchMap 獲取這些值,取消訂閱(并因此取消)先前的請求并開始新的請求

在此流程中您可能沒有預料到的是,無論何時設置 limit ,此更改都會在更改 offset 之前直接傳播到 combineLatest.

如何避免這個行為

如果有一種方法可以確保在同一個調用堆棧中發生的更改(這是單擊重置按鈕時發生的情況)被丟棄以支持最后一次更改,我們可以解決我們的問題。

這意味著,當 combineLatest 在同一個調用堆棧中發出兩個值時,當調用堆棧被清除時,最后一個值將被發送。

為此,我們可以在 combineLatest 之后直接利用值為 0 的 debounceTime。 這將確保只有最后一個值被傳遞給 switchMap,并且在調用堆棧被清除之后。

每當提到“在同一個調用堆棧中”時,都可以將其替換為“在事件循環的同一輪次中發生的更改”。

加上了 debounceTime(0) 之后的時序圖:

  • combineLatest 保存所有源流的最后一個值,開始場景是,limit = 8,offset = 2
  • 單擊重置按鈕
  • 限制設置為 5
  • combineLatest 運算符看到一個新值進入 limit 并發出一個新組合,limit = 5,offset = 2
  • debounceTime 運算符看到一個新值,并且(因為操作符的值為 0)將等待直到調用堆棧被清除以將其傳遞
  • 偏移量設置為 0
  • combineLatest 運算符看到一個新的 offset 值,并發出一個新的組合,limit = 5,offset = 0
  • debounceTime 運算符再次看到一個新值,將丟棄舊值,并等待堆棧被清除以將其傳遞
  • 調用堆棧被清除
  • debounceTime 運算符沒有看到新的值,將通過組合,limit = 5,offset = 0 向下游發送數據
  • switchMap 操作符獲取這些值并訂閱觸發后端調用的流

修復代碼非常簡單,加上一行代碼即可:

debounceTime(0),

修復后的效果,點擊 reset 按鈕之后,只有一次 HTTP 請求發出了:

更多Jerry的原創文章,盡在:“汪子熙”:

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的combineLatest 使用的一个陷阱和基于 debounceTime 的解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。