如何异步填充集合?

时间:2017-07-26 10:51:29

标签: asynchronous rxjs

我试图通过以异步方式将产品添加到每个超市来填充超市的集合。

目标是通过这样的事情来传递:

[{
    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

谢谢!

1 个答案:

答案 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是我们要发出的普通对象。