淺談Angular中RxJS如何映射資料操作
Map
資料是程式開發時的常見操作。當程式碼中使用RxJS
來產生資料流時,很可能最終需要一種方法來將資料對應成需要的任何格式。 RxJS
提供了常規的map
函數,還有mergeMap
、switchMap
和concatMap
這樣的函數,它們的處理方式略有不同。 【相關教學推薦:《angular教學》】
map
map
運算子是最常見的。對於Observable
發出的每個值,都可以套用一個函數來修改資料。傳回值將在背景被重新釋放為Observable
,這樣就可以在流中繼續使用它。它的工作原理與在數組中使用它的方法非常相似。
不同之處在於,數組將始終只是數組,而在映射時,將獲得數組中當前的索引值。對於observable
,資料的型別可以是各種型別。這意味著可能需要在 Observable map
函數中做一些額外的操作來獲得想要的結果。看下面的範例::
import { of } from "rxjs"; import { map } from "rxjs/operators"; // 创建数据 const data = of([ { brand: "保时捷", model: "911" }, { brand: "保时捷", model: "macan" }, { brand: "法拉利", model: "458" }, { brand: "兰博基尼", model: "urus" } ]); // 按照brand model的格式输出,结果:["保时捷 911", "保时捷 macan", "法拉利 458", "兰博基尼 urus"] data.pipe(map(cars => cars.map(car => `${car.brand} ${car.model}`))).subscribe(cars => console.log(cars)); // 过滤数据,只保留brand为porsche的数据,结果:[{"brand":"保时捷","model":"911"},{"brand":"保时捷","model":"macan"}] data.pipe(map(cars => cars.filter(car => car.brand === "保时捷"))).subscribe(cars => console.log(cars));
首先用一系列汽車建立了可觀察物件。然後訂閱這個可觀測值2次。
第一次修改資料時,得到了一個由
brand
和model
字串連接起來的陣列。第二次修改資料時,得到了一個只有
brand
為保時捷
的陣列。
在這兩個範例中,使用Observable
map運算子來修改由Observable
所發出的資料。傳回修改的結果,然後map
運算子將結果封裝到一個可觀察物件中,以便後面可以subscribe
。
MergeMap
現在假設有這樣一個場景,有一個可觀察到的對象,它發出一個數組,對於數組中的每一項,都需要從伺服器獲取數據。
可以透過訂閱陣列來做到這一點,然後設定一個映射來呼叫一個處理API呼叫的函數,訂閱其結果。如下:
import { of, from } from "rxjs"; import { map, delay } from "rxjs/operators"; const getData = param => { return of(`检索参数: ${param}`).pipe(delay(1000)); }; from([1, 2, 3, 4]) .pipe(map(param => getData(param))) .subscribe(val => console.log(val));
map
函數傳回getData
函數的值。在這種情況下,這是可觀測的。但這產生了一個問題:因為現在要處理一個額外的可觀測值。
為了進一步闡明這一點:from([1,2,3,4])
作為「外部」可觀察對象,getData()
的結果作為“內部”可觀察對象。從理論上講,必須同時接受外部和內部的可觀測資料。可以是這樣的:
import { of, from } from "rxjs"; import { map, delay } from "rxjs/operators"; const getData = param => { return of(`检索参数: ${param}`).pipe(delay(1000)); }; from([1, 2, 3, 4]) .pipe(map(param => getData(param))) .subscribe(val => val.subscribe(data => console.log(data)));
可以想像,這與必須調用Subscribe
兩次的理想情況相去甚遠。這就是mergeMap
發揮作用的地方。 MergeMap
本質上是mergeAll
和map
的組合。 MergeAll
負責訂閱「內部」可觀察對象,當MergeAll
將「內部」可觀察對象的值合併為「外部」可觀察對象時,就不再需要訂閱兩次。如下:
import { of, from } from "rxjs"; import { map, delay, mergeAll } from "rxjs/operators"; const getData = param => { return of(`检索参数: ${param}`).pipe(delay(1000)); }; from([1, 2, 3, 4]) .pipe( map(param => getData(param)), mergeAll() ) .subscribe(val => console.log(val));
這已經好多了,mergeMap
將是這個問題的最佳解決方案。以下是完整的範例:
import { of, from } from "rxjs"; import { map, mergeMap, delay, mergeAll } from "rxjs/operators"; const getData = param => { return of(`检索参数: ${param}`).pipe(delay(1000)); }; // 使用 map from([1, 2, 3, 4]) .pipe(map(param => getData(param))) .subscribe(val => val.subscribe(data => console.log(data))); // 使用 map 和 mergeAll from([1, 2, 3, 4]) .pipe( map(param => getData(param)), mergeAll() ) .subscribe(val => console.log(val)); // 使用 mergeMap from([1, 2, 3, 4]) .pipe(mergeMap(param => getData(param))) .subscribe(val => console.log(val));
SwitchMap
#SwitchMap
有類似的行為,它也會訂閱內部可觀察物件。然而,switchMap
是switchAll
和map
的組合。 SwitchAll
取消先前的訂閱並訂閱新訂閱。在上面的場景中,想要為「外部」可觀察物件數組中的每一項執行API調用,但switchMap
並不能很好地工作,因為它將取消前3個訂閱,只處理最後一個訂閱。這意味著只會得到一個結果。完整的例子可以在這裡看到:
import { of, from } from "rxjs"; import { map, delay, switchAll, switchMap } from "rxjs/operators"; const getData = param => { return of(`retrieved new data with param ${param}`).pipe(delay(1000)); }; // 使用 a regular map from([1, 2, 3, 4]) .pipe(map(param => getData(param))) .subscribe(val => val.subscribe(data => console.log(data))); // 使用 map and switchAll from([1, 2, 3, 4]) .pipe( map(param => getData(param)), switchAll() ) .subscribe(val => console.log(val)); // 使用 switchMap from([1, 2, 3, 4]) .pipe(switchMap(param => getData(param))) .subscribe(val => console.log(val));
雖然switchMap
不適用於當前的場景,但它適用於其他場景。例如,如果將篩選器清單組合到資料流中,並在更改篩選器時執行API調用,那麼它將派上用場。如果先前的篩選器變更仍在處理中,而新的變更已經完成,那麼它將取消先前的訂閱,並在最新的變更上啟動新的訂閱。這裡可以看到一個例子:
import { of, from, BehaviorSubject } from "rxjs"; import { map, delay, switchAll, switchMap } from "rxjs/operators"; const filters = ["brand=porsche", "model=911", "horsepower=389", "color=red"]; const activeFilters = new BehaviorSubject(""); const getData = params => { return of(`接收参数: ${params}`).pipe(delay(1000)); }; const applyFilters = () => { filters.forEach((filter, index) => { let newFilters = activeFilters.value; if (index === 0) { newFilters = `?${filter}`; } else { newFilters = `${newFilters}&${filter}`; } activeFilters.next(newFilters); }); }; // 使用 switchMap activeFilters.pipe(switchMap(param => getData(param))).subscribe(val => console.log(val)); applyFilters();
正如在控制台中看到的,getData
只記錄一次所有參數。節省了3次API的呼叫。
ConcatMap
最後一個例子是concatMap
。 concatMap
訂閱了內部可觀察物件。但與switchMap
不同的是,如果有一個新的觀察對象進來,它將取消當前觀察對象的訂閱,concatMap
在當前觀察對象完成之前不會訂閱下一個觀察對象。這樣做的好處是保持了可觀測物件發出訊號的順序。為了示範這個:
import { of, from } from "rxjs"; import { map, delay, mergeMap, concatMap } from "rxjs/operators"; const getData = param => { const delayTime = Math.floor(Math.random() * 10000) + 1; return of(`接收参数: ${param} and delay: ${delayTime}`).pipe(delay(delayTime)); }; // 使用map from([1, 2, 3, 4]) .pipe(map(param => getData(param))) .subscribe(val => val.subscribe(data => console.log("map:", data))); // 使用mergeMap from([1, 2, 3, 4]) .pipe(mergeMap(param => getData(param))) .subscribe(val => console.log("mergeMap:", val)); // 使用concatMap from([1, 2, 3, 4]) .pipe(concatMap(param => getData(param))) .subscribe(val => console.log("concatMap:", val));
getData
函数的随机延迟在1到10000毫秒之间。通过浏览器日志,可以看到map
和mergeMap
操作符将记录返回的任何值,而不遵循原始顺序。concatMap
记录的值与它们开始时的值相同。
总结
将数据映射到所需的格式是一项常见的任务。RxJS
附带了一些非常简洁的操作符,可以很好的完成这项工作。
概括一下:map
用于将normal
值映射为所需的任何格式。返回值将再次包装在一个可观察对象中,因此可以在数据流中继续使用它。当必须处理一个“内部”观察对象时,使用mergeMap
、switchMap
或concatMap
更容易。如果只是想将数据转成Observable
对象,使用mergeMap
;如果需要丢弃旧的Observable
对象,保留最新的Observable
对象,使用switchMap
;如果需要将数据转成Observable
对象,并且需要保持顺序,则使用concatMap
。
更多编程相关知识,请访问:编程视频!!
以上是淺談Angular中RxJS如何映射資料操作的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Angular.js是一種可自由存取的JavaScript平台,用於建立動態應用程式。它允許您透過擴展HTML的語法作為模板語言,以快速、清晰地表示應用程式的各個方面。 Angular.js提供了一系列工具,可協助您編寫、更新和測試程式碼。此外,它還提供了許多功能,如路由和表單管理。本指南將討論在Ubuntu24上安裝Angular的方法。首先,您需要安裝Node.js。 Node.js是一個基於ChromeV8引擎的JavaScript運行環境,可讓您在伺服器端執行JavaScript程式碼。要在Ub

angular中怎麼使用monaco-editor?以下這篇文章記錄下最近的一次業務中用到的 monaco-editor 在 angular 中的使用,希望對大家有幫助!

隨著網路的快速發展,前端開發技術也不斷改進與迭代。 PHP和Angular是兩種廣泛應用於前端開發的技術。 PHP是一種伺服器端腳本語言,可以處理表單、產生動態頁面和管理存取權限等任務。而Angular是一種JavaScript的框架,可以用來開發單一頁面應用程式和建構元件化的網頁應用程式。本篇文章將介紹如何使用PHP和Angular進行前端開發,以及如何將它們

如何使用PHP實現批次處理和資料批量操作在開發Web應用程式過程中,經常會遇到需要同時處理多個資料的情況。為了提高效率和減少資料庫請求的次數,我們可以使用PHP來實現批次處理和資料批量操作。本文將介紹如何使用PHP來實現這些功能,並附加程式碼範例以供參考。批次處理資料當需要對大量資料進行相同的操作時,可以使用PHP的循環結構來進行批次處理。

這篇文章帶大家了解Angular中的獨立元件,看看怎麼在Angular中建立一個獨立元件,怎麼在獨立元件中導入已有的模組,希望對大家有幫助!

身份驗證是任何網路應用程式中最重要的部分之一。本教程討論基於令牌的身份驗證系統以及它們與傳統登入系統的差異。在本教程結束時,您將看到一個用Angular和Node.js編寫的完整工作演示。傳統身份驗證系統在繼續基於令牌的身份驗證系統之前,讓我們先來看看傳統的身份驗證系統。使用者在登入表單中提供使用者名稱和密碼,然後點擊登入。發出請求後,透過查詢資料庫在後端驗證使用者。如果請求有效,則使用從資料庫中獲取的使用者資訊建立會話,然後在回應頭中傳回會話訊息,以便將會話ID儲存在瀏覽器中。提供用於存取應用程式中受
