在订阅我的Observable时,我面临一种奇怪的行为。
由于某些原因,从未调用console.log(item)
,并且控制台上也没有错误。
this.store$
.pipe(
select(getRecentNotes),
mergeAll(),
groupBy(item => item.status.code),
mergeMap(group => group.pipe(toArray())),
toArray()
)
.subscribe((items)=> console.log('Grouped Items', items));
顺便说一句,如果我仅管道传输 select(getRecentNotes)
,那么它将正常工作,并且我得到的是这样的内容:
[
{id: 1, note: "ABC", status: {code: 1, name: 'active'}},
{id: 2, note: "DEF", status: {code: 1, name: 'active'}},
{id: 3, note: "HIJ", status: {code: 2, name: 'hidden'}}
]
更有趣的是,以下将起作用:
// This will work
this.store$
.pipe(
select(getRecentNotes),
mergeAll()
)
.subscribe((items)=> console.log('Bunch of Items', items));
但是,如果我添加了另一个运算符,例如toArray(),它将停止工作。
// This will not work
this.store$
.pipe(
select(getRecentNotes),
mergeAll(),
toArray()
)
.subscribe((items)=> console.log('All items', items));
有没有我遗漏的隐藏规则?
我试图使用一个简单的Observable.from([])
在StackBlitz上重现该问题,但一切似乎都可以正常工作。
更新1: 我在管道中添加了其他一些运算符,它们可以完成操作(例如打印到控制台)。但是.subscribe中的代码没有被调用
this.store$
.pipe(
select(getRecentNotes),
mergeAll(),
tap((item)=> {console.log(item)}), // <--- This is printed to the console
reduce((acc, item)=> {
console.log(acc); // <-- This is printed to the console
console.log(item);
return acc.push(item);
},[])
)
.subscribe((items)=> console.log('All items', items));
答案 0 :(得分:1)
正如@AnjilDhamala在评论中提到的那样,toArray
之类的运算符直到流完成才执行。您的商店$可观察的价格保持开放状态,以便toArray
运算符永远不会发出结果。
似乎您的目标是返回由代码分块的数组的数组?
简单的解决方法是在take(1)
操作员调用之后添加select
。这应该导致最后一个toArray
返回一个数组数组。
但是,如果我的假设是正确的,那么所有这些可能都是不必要的。看起来使用所有这些rxjs运算符似乎是干净的,但是您要完成的工作的意图还很不清楚。在select
之后,您可以使用一个函数来调用map
,该函数将使用普通的旧JavaScript将您的数组分块。
this.store$
.pipe(
select(getRecentNotes),
map(x => chunkBy(x, x => x.status.code))
).subscribe((items)=> console.log('All items', items));
function chunkBy<T>(ary: T[], chunkKeySelector: (item: T) => any) {
const result: T[][] = [];
const indexMap = new Map<any, number>();
for (let value of ary) {
const key = chunkKeySelector(value);
(indexMap.has(key))
? result[indexMap.get(key)].push(value)
: indexMap.set(key, result.push([value]) - 1);
}
return result;
}