我试图通过以异步方式将产品添加到每个超市来填充超市的集合。
目标是通过这样的事情来传递:
[{
name: 'supermarket x',
products: [1, 2]
}]
更像这样的事情:
[{
name: 'supermarket x',
products: [{
id: 1,
name: 'cacao'
}, {
id: 2,
name: 'milk'
}]
}]
我必须为此制作基本代码,但是一旦完成,我无法用第二个流填充第一个流。
有什么想法吗?
我留下了一个带有结构的JSBin,以便让你更快
https://jsbin.com/nucutox/1/edit?js,console
谢谢!
答案 0 :(得分:1)
因此,您有一个getSupermarkets()
函数,它返回一个发出多个超市对象的流和一个getProduct(id)
函数,该函数返回一个流,该流发出具有指定id的单个产品,然后完成。并且您希望将包含产品ID的超市流映射到包含“已解决”的产品对象的超市流。我做对了吗?
这是我的解决方案:
const supermarkets$ = getSupermarkets()
.concatMap(supermarket => {
const productStreams = supermarket.products
.map(productId => getProduct(productId));
return Rx.Observable.combineLatest(productStreams)
.map(products => Object.assign({}, supermarket, { products }));
});
supermarkets$.subscribe(x => console.log(x));
当一个新的超市对象到来时,我们首先将其产品ID数组映射到一个产品可观察数组,即Array<Id> => Array<Observable<Product>>
。然后我们将该数组传递给combineLatest
运算符,该运算符等待直到每个observable产生一个值并发出这些值的数组,即产品对象数组。然后我们生成一个新的超市对象,其中products
设置为数组。我们希望原始supermarket
对象保持不变,这就是为什么Object.assign
。
为了使其有效,我必须稍微更新getProduct()
的实现:使用.of(product)
运算符而不是.from(product)
,因为product
是我们要发出的普通对象。