[英]Best way to get value of RxJs Observable in a nested array of objects to resolve?
[英]Best way to “flatten” an array inside an RxJS Observable
我的后端经常将数据作为RxJS 5 Observable 中的数组返回(我使用的是 Angular 2)。
我经常发现自己想要使用 RxJS 运算符单独处理数组项,并且我使用以下代码 ( JSBin ) 这样做:
const dataFromBackend = Rx.Observable.of([
{ name: 'item1', active: true },
{ name: 'item2', active: false },
{ name: 'item3', active: true }
]);
dataFromBackend
// At this point, the obs emits a SINGLE array of items
.do(items => console.log(items))
// I flatten the array so that the obs emits each item INDIVIDUALLY
.mergeMap(val => val)
// At this point, the obs emits each item individually
.do(item => console.log(item))
// I can keep transforming each item using RxJS operators.
// Most likely, I will project the item into another obs with mergeMap()
.map(item => item.name)
// When I'm done transforming the items, I gather them in a single array again
.toArray()
.subscribe();
mergeMap(val => val)
行感觉不太习惯。
有没有更好的方法可以将转换应用于 Observable 发出的数组成员?
注意。 我想要 RxJS 运算符(与数组方法)来转换我的项目,因为我需要能够将每个项目投影到第二个 observable 中。 典型用例:后端返回项目 ID 列表,我需要从后端请求所有这些项目。
您可以不带任何参数使用concatAll()
或mergeAll()
。
dataFromBackend.pipe(
tap(items => console.log(items)),
mergeAll(), // or concatAll()
)
这(包括mergeMap
)仅在 RxJS 5 中有效,因为它以相同的方式处理 Observables、数组、类数组对象、Promises 等。
最终你也可以这样做:
mergeMap(val => from(val).pipe(
tap(item => console.log(item)),
map(item => item.name),
)),
toArray(),
2019 年 1 月:针对 RxJS 6 更新
实际上,如果您在流中需要它,只需使用它:
.flatMap(items => of(...items))
角 6 注释。
如果您用作可管道操作符,则 do 称为 tap!
https://www.learnrxjs.io/operators/utility/do.html这是一个例子。
// RxJS
import { tap, map, of, mergeMap} from 'rxjs/operators';
backendSource
.pipe(
tap(items => console.log(items)),
mergeMap(item => item ),
map(item => console.log(item.property))
);
如果是同步操作,我建议使用 javascript 的Array.map
代替,它甚至应该为您节省一些性能:
const dataFromBackend = Rx.Observable.of([
{ name: 'item1', active: true },
{ name: 'item2', active: false },
{ name: 'item3', active: true }
]);
dataFromBackend
.map(items => items.map(item => item.name))
.subscribe();
我有一个类似的问题:
下列
this.metaData = backendPostReq(body)
.pipe(
mergeMap(item => item), // splits the array into individual objects
pluck('metaData', 'dataPie', 'data'), // plucks deeply nested property
toArray() // converted back to an array for ag grid
)
<ag-grid-angular
*ngIf="metaData | async as result"
[gridOptions]="dataCollectionConfig"
[rowData]="result"
[modules]="modules"
class="ag-theme-balham data-collection-grid"
>
</ag-grid-angular>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.