为什么第二个示例的订阅方法未调用?
两个示例中管道中的所有日志均按预期方式工作。
工作示例:(但使用硬编码的数据和创建者):
of([
{tableName: 'table1', firstName: 'name1', lastName: 'lastName1'},
{tableName: 'table1', firstName: 'name2', lastName: 'lastName2'},
{tableName: 'table2', firstName: 'name3', lastName: 'lastName3'},
{tableName: 'table2', firstName: 'name4', lastName: 'lastName4'}
]).pipe(
tap(data => console.log('amount of records', data.length)),
mergeMap((searchResult) => searchResult),
groupBy(b => b.tableName),
mergeMap(group => {
console.log('groupKey', group.key);
return group.pipe(toArray());
})
).subscribe(val => console.log(val));
问题代码:(直接使用来自ngrx商店的数据,并且数据结构与上面的代码工作示例相同)
this.store.pipe(
select(selectSearchResult),
tap(data => console.log('amount of records', data.length)),
mergeMap((searchResult) => searchResult),
groupBy(b => b.tableName),
mergeMap(group => {
console.log('groupKey', group.key);
return group.pipe(toArray());
})
).subscribe(val => console.log(val)); // <- this is not called!?
我希望每个组都调用subscription方法,因为 上面带有硬编码数据的示例。但是具有讽刺意味的是没有订阅方法吗?!
商店交付的商品不在阵列中的示例:
答案 0 :(得分:1)
我认为问题出在这里
商店是可观察到的长寿。这意味着:它本身不会完成。
toArray
收集有关其源流的所有通知,直到该流完成,然后仅发送一条包含项数组的通知。
否则,如何知道何时准备将数组发送给下一个运算符?总是会有另一个通知,可能会使数组更大。
请注意,由GroupedObservable
产生的groupBy
在完成其来源之前是不会完成的。由于源store
不会完成,因此toArray
将永远不会收到complete
消息。
解决方案是:重构代码,以便使用from
获得可观察的结果。 from
将数组作为参数,为每个数组项发送一个通知,然后发送完整通知,向toArray
表示它可以发送通知。这应该起作用:
mergeMap((searchResult) =>
from(searchResult).pipe(
groupBy(b => b.tableName),
mergeMap(group => {
console.log('groupKey', group.key);
return group.pipe(toArray());
})
))
来源:RxJS Code请看GroupedObservable何时完成。
答案 1 :(得分:0)
它认为您将groupBy作为在数组而不是流上使用的函数感到困惑,RxJs函数适用于流,而不适用于流所发出的值。
groupBy不对流发出的数组进行分组,而是对流进行分组。就像每次可观察对象发出一个对象一样,它被添加到组中。如果要对存储中的数组进行分组,则需要与数组一起使用的groupBy函数。
这是我编写的带数组https://stackblitz.com/edit/typescript-ezydzv
的groupBy函数的示例map是RxJs函数,用于操纵流发出的对象,并且可以在map中将groupBy应用于数组。
this.store.pipe(
select(selectSearchResult),
tap(data => console.log('amount of records', data.length)),
map(data => groupBy(data, { keys: ['tableName'] }))
).subscribe(val => console.log(val));